NEON is the ARGON user interface framework.

Logging in

An ARGON node with a human interface - a desktop PC, a laptop, or a table or smartphone, or whatever the future brings us - will run the NEON kernel component to manage it. This means it will, on boot, present a login interface allowing a user to log on.

There is no "user database" in ARGON, with usernames and passwords. Logging on involves selecting your user agent entity to specify who you are, then doing whatever authentication that user agent demands to prove it's you accessing it.

In this day and age, computers with human interfaces are normally owned by a single person, or a small set of people within a family, so the IDs of those user agents will be known to the device and you'll just pick yourself from a list then log on. But unless the device is configured to be locked down to a limited list of users, you will also be able to enter the CARBON name of any user agent, or browse CARBON interactively, allowing anybody with a user agent somewhere on the Internet to log onto any device.

Just to clarify terminology: The "user interface" (UI) is the ARGON node you're physically using, with screens and keyboards and pointing devices and speakers or whatever attached. The "user agent" (UA) is an entity somewhere that is your "account". The UI and the UA needn't have any special pre-existing relationship.

When you've selected a user agent, the NEON kernel module on the device will use CARBON to ask that entity for its user interface module. This will be a reference to a CHROME software module that will be downloaded to the device and executed, in a context that has access to all the user-interface hardware on that device. This is nominated by the user agent and works in close cooperation with it, so is known as the "Local User Agent", or LUA.

This is unlike most execution of software in ARGON, which occurs with an entity context with access to the state of an entity. This code, running on a device that doesn't trust it any further than the fact that a human touching the device has asked the device to run this code, is given nothing more than access to the user interface hardware, the network via MERCURY, and some CPU and RAM to execute code in.

The first job of that local user agent will be to authenticate that the user is the real owner of the user agent. Probably by asking for a password. There's an issue of trust here - the user has to trust the user interface hardware they're using, to neither record their interactions in order to store their password somewhere, nor to let them log in then take over or clone their session to let somebody else interact with their user agent once authenticated. This is exactly the same trust issue as when somebody logs into their online accounts with a Web browser, and the same user education will be required to encourage people to think carefully about what random computers they type their passwords into. Perhaps a useful feature for a user agent will be to allow the user to log in with a "lower tier" password that provides limited access to their "stuff", for use on less trusted devices.

Anyway, the local user agent code running in the NEON context is told the entity ID of the user agent the user is trying to connect to (it doesn't have to have it hardcoded, so the same LUA code can be shared between multiple user agent entities), so it will probably open a MERCURY connection to it, and mediate the authentication process between the user and the user agent entity within the context of that connection. The end result is a connection to the user agent that the user agent is able to authenticate as having been opened by its owner: an authenticated user session, in effect.

At this point, the user agent will probably create a certificate (see the Security page for more about the mechanisms) that can be used by the LUA to authenticate MERCURY connections as the user agent - or maybe a certificate issued by a pseudonym from the user's stash. Either way, the actual private key used to authenticate the user agent entity (which is the private key of the volume hosting that entity!) or the private key of the pseudonym keypair is not revealed to the LUA - just a certificate signed by it giving the LUA a time-limited right to act under that identity.

New certificates will be issued down the connection before the old ones expire, so an expiry time of a minute or two is perfectly reasonable. If the UI device isn't particularly trusted, this process may also involve re-authenticating the user periodically, in case the LUA session has been "hijacked" and is no longer actually under the user's control. If the authentication process doesn't just involve repeating a password but involves some kind of challenge/response protocol, this might even be mildly secure against untrustworthy UIs (but it still gives them free reign to impersonate whatever identity the user interface is trusted with while your session IS open).

So, the running LUA code how has the ability to issue MERCURY requests in the name of the user's chosen identity, and has a secure connection to the user agent, and it can now do its job: allow the user to interact with entities through MERCURY using their identity, and allow the user to interact with their own private stuff inside their user agent.

Other options

FIXME: The above is just a convention for general purpose UI/UA logins. You can also use the UI to browse to any entity that provides the NEON "top-level user interface" reference in CARBON - what other entities than UAs might do that? It gives them low-level access to raw UI hardware, but nothing else, and runs the code in an anonymous context without any private keys to authenticate to anything with. You could write a Web browser or (free) games or other such applications that runs in this context?

Once a user session is established

Exactly how the LUA presents an interface to the user is entirely up to it. It's got raw access to whatever user interface hardware the UI device has - almost certainly a graphical display surface, probably sound output, usually either a mouse/trackball or a touch screen, maybe a keyboard, maybe sound input and one or more cameras and acceleration sensors and positioning devices and fingerprint scanners and so on.

In general, it has two main jobs: interacting with arbitrary entities out there in the ARGON world, via MERCURY - and interacting with the user's own private stuff inside their user agent. Let's look at each in detail.

Interacting with arbitrary entities

Identifying entities

The first step is picking an entity, which could happen in four main ways:

One concern here is that users are actually interacting with the entity they mean to interact with, which can be a big deal if the entity controls something important (their bank account, for instance). In the world of the Web, we have a whole bunch of complexity around the workings of TLS and X.509 and user interface elements in browsers to try and avoid trouble. Although the ARGON security architecture makes this a lot simpler, the same basic problems remain.

Unlike URLs, Entity IDs contain embedded cryptographic keys, so when we contact the entity, we can be sure that we talk to the actual entity and not an imposter. However, entity IDs are unreadable; user's can't look at them and recognise them, so the burden of security is put on where the entity IDs come from.

When resolving a CARBON name, ARGON traces a path from a trusted "root entity" (whose ID is well known) down through a chain of entities responsible for particular parts of the global namespace, to the target entity (or a failure, if it doesn't exist). Each step in that path involves the parent entity replying with the EID of the next level down, so a chain of trust is made from the root entity down to the actual entity you want. So as long as the publisher of that name is correct to trust whatever authority they obtain a delegation of their parent name from, and so on up the chain to the root, we're good. This is pretty much how DNSSEC works, and has the same trust model.

If the user has a bookmarked entity ID, they're trusting their user agent to have remembered it correctly when they bookmarked it, which is hopefully a justified trust or all hope is lost.

If the user interactively browses the CARBON namespace, then that's just like entering a CARBON name - after all, a CARBON name just gives a name to a sequence of navigational steps. The user interface can even display the CARBON name of the entity they're looking at as they browse.

If the user finds an entity ID in something they get from some random entity, then who knows what claims that entity may have made about what it is? So the user interface must be careful to make sure that random entities can't make it seem like they're the CARBON namespace browser or the user agent's bookmark list, so it's clear to the user who is making the claims they're reading.

In order to prevent entities from using tricks to confuse users as to what they're talking to, user agents should do a good job of making the context of an interaction with an entity clear. How do we tell the user what entity they're talking to in a way that's hard to confuse, when entity IDs are opaque blobs of hash? We can use that EID to ask the entity what its name is (via CARBON), but it can lie.

A good way of doing that is with a system called Petnames. The user agent can keep an "address book" of entity IDs the user has encountered (even in passing; not just ones the user has asked to "bookmark") and where it found them - either in the CARBON namespace (in which case, it remembers the CARBON name) or from some other source (in which case it records the EID of that source, and the name that source gave it - like the text of a hyperlink; note that the source might be a signed CARBON knowledge packet, in which case there are multiples sources to record - the one that provided the packet, and the one(s) whose signature(s) is/are on the packet). A given EID may be found from multiple sources, of course; so each entry needs to store a list of sources - with a timestamped log of when it was found through each source.

It also stores other metadata, as will be elaborated soon. And finally, it can cache the entity's self-proclaimed name obtained by asking it, so that doesn't need to be repeated frequently.

It can then present the user with a "safe name" for any EID they find. If the EID has a CARBON name in the address book, it can display the name as something like "(CARBON name): '(Entity's self-name)'" - so no matter what the entity calls itself, its CARBON name is foremost. If there's more than one CARBON name, it can use some heuristic to find the "best", perhaps based on the timestamped log (which one did the user find first, perhaps?).

If not, it can look up the EID that provided this EID and recursively find a name for that, then name this entity something like "(name given by source entity) according to (name of source entity): '(Entity's self-name)'". If the source entity doesn't have a nice short name in the address book this might involve an arbitrary path of EIDs leading to one with a CARBON name, or maybe it leads to a dead end and a raw EID with no name we can find, in which case we just need to display it as "unknown" or something.

Either way:

As an extension to this, it would be possible for entities to publish information about arbitrary EIDs in CARBON. Perhaps trade organisations can publish lists of their members (maybe with extra metadata about their certifications and qualifications and whatnot), perhaps friends can share their bookmark lists with each other, perhaps there can be collaborative directories. Either way, it could be possible for a user agent to be configured to refer to a third-party information entity to obtain names (and other metadata) about entities, which they can use as an additional source of information alongside their own address book.

All of this is down to the user agent (and its local user agent), however. Different ones can handle it differently, and approaches can evolve with time.

User agent services

Your user agent represents you in the world of ARGON; it lets you publish your own information in CARBON, from profile data (name and other personal details) to blog posts, whether you're interested in a job, and so on. And it provides other MERCURY interfaces to allow interaction with you. The most crucial of which is probably Object Push from the IODINE interface library, by which people can send you things. As object push allows sending arbitrary serialised CARBON knowledge packets, they might be anything from simple messages with attachments to more complicated and interesting objects such as invites to join an event or a community or something, or requests to do a task; if you do a desk job, rather than having a "ticket tracking system" managing tasks for the team by making you go and check it, the team management entity will send task objects to your user agent (with a link back to the task itself, which is of course an entity).

Of course, you can use access control lists to restrict who gets to do what. A very basic set of information and capabilities might be made public, with more intimate knowledge and powers granted to people on your "friend lists" (a set of access control list, under the hood).

The user agent provides a user interface to you, through the local user agent, to update your core details, publish things in your public feed, configure what services you provide to the world and how they work. Rather than requiring a user agent to be a massive monolith of code that understands all of these different applications, they should be built as modular platforms that combine a control user interface to run inside the local user agent, code to run in the user agent itself to provide public MERCURY interfaces, and code to run in the user agent to extend the private MERCURY interface exposed to the local user agent so the front-end part can communicate with the back-end part. Such modules would also register handlers for particular types of objects found in CARBON, providing a custom user interface for such objects wherever they are found - stored inside the user agent itself, received via an object push, found in other entities via CARBON, and so on. The module would also be given a slice in the entity's TUNGSTEN state to manage for its internal private state storage, and the ability to request one or more slices to be published via CARBON. The ability to have multiple public slices exists purely so the published state can be divided into separate sections that can have their own ACLs, if differing levels of access to different groups are required.

You might install modules for:

The kinds of things one installs an application on one's device for would be user agent modules in the ARGON world, and the interface a user agent provides for modules to hook into its behaviour would probably look somewhat familiar to an Android or iOS developer. This also means there has to be a way for such a module to be installed inside the user agent. The module is just a CHROME code module, published in CARBON somewhere, but marked as being a user agent module in its type metadata so the UA knows (via a plugin registered to that object type!) to present the option of installing it, by loading its code and invoking the appropriate interfaces in it to do an initial setup of its private state, then to ask it what user agent behaviours it wants to hook into and setting that up in the user agent's state. In fact, to avoid user confusion, such user agent extension modules should probably just be called "apps"...

However, that interface is provided by the user agent - and there's nothing to say there can't be a proliferation of user agent software for users to choose from. Hopefully, sets of user agents following a shared model to some extent or another can share the same module interface and use the same modules, but widely different user agent paradigms might need different extension module architectures.

Note that the private storage slice for a module is for storing its state and configuration as an installed module inside this user agent. If the module is a plugin for a given data type, such as a musical score, then it wouldn't normally store the stuff it edits in its private slice - just configuration and settings. It would be used to display musical scores it finds out there in CARBON; it might be asked to create a musical score if you want to send one to somebody in an object push, or as part of some other user interface task are faced with a dialog asking you to provide a musical score. If you just ask your user agent to create a musical score for you to edit through a generic "Create new object" button, it will store it in a general "stuff the user has created" slice (sort of a "My Documents").

Note also that in the entities page we discuss document entities, which publish something in CARBON. A data type plugin in a user agent will be invoked to display that state, but what if you edit it? Well, sticking with the example of a musical score, we could take the musical score published by an entity and edit it using an editing plugin you have to create a modified musical score object, which will now be sitting around inside your user agent. We could then object-push the resulting score back to the document entity which, if we have sufficient ACL permissions, will accept it as a new commit to add to the version history, and depending on its configuration (and where you sit in its ACLs) either create a new branch that somebody can review and merge, or just make it the new current version. The document entity itself doesn't need document-type specific code to handle this; it just stores a version history of arbitrary CARBON knowledge packets, and relies on user agents to identify the type of the object inside and offer appropriate editing interfaces.

However, that's distinct from the kind of collaborative interactive editing you get with Google Docs. Implementing that requires very document-type-specific logic, so document entities that support that will probably be restricted to a specific kind of document. They'll present the object for viewing as usual, but they'll also publish a reference to a direct interaction user interface module (which we elaborated below) for user interaction with the entity, and then use that to present a live collaborative editing interface, with the front-end component running in the user's UI and talking to a backend component inside the entity.

Interaction: building actual user interfaces

I've talked about general principles here, but when some code actually wants to talk to the user, how will that work?

To recap, there's a few contexts where this might happen:

Now, if the user navigates to an entity that exposes the "raw" UI interface, like a user agent does, there's no reason a user agent can't emulate a raw user interface and just download the entity's offered LUA code and run it with a raster display embedded in a window and feed in raw mouse and keyboard events or whatever.

But that's not how entities should provide their user interface; it's too low level. Normally, entities will publish a user interface using the high-level user interface protocol. Ok, a user agent will often provide both - the raw interface for its owner to use it as a user agent and get their favourite customers user interface from their local user agent, and the high-level user interface protocol for third parties to interact with the user agent to send the owner messages or whatever through their annoying customised interface.

The high level direct interaction interface an entity can publish is, as you might expect, just a pointer to some CHROME code to fetch from carbon, that is executed in the local user agent in a sandbox, restricted so it can only interact with the entity, customising how its CARBON published knowledge is displayed (if required) and providing custom command user interface to send MERCURY requests back.

The programming interface to actually interact with the user, however, is the same for all of these contexts. Rather than being directly tied to a 2D graphical interface, however, I propose an interface more like CLIM, the Common List Interface Manager; the user agent can implement this in terms of a graphical or textual interface, and thereby allow a combination of user preference, adapting a user interface to work on tiny mobile or massive desktop displays with varying interface hardware, and most crucially, allow (where practical) the same interface to be used by able-bodied and disabled people with assistive technologies. Of course, some things just won't make sense in all representations, so there will be some limits - a 3D model is hard to represent through a speech synthesiser, although perhaps an implementation could still have a bash at it.

And, again, their might be multiple user agent paradigms kicking around, each of which necessitates a different programming interface for plugins and user interface code and so on. Object types and entities may need to publish code for multiple different paradigms.