The term peer or node refer to an entity that is connected to other such entities with some kind of network technology. Ethernet and Internet are examples of such technology. Generally, in Kueea System documents, nodes refer to a single thing, whereas peers are used in the context of a pair of nodes.
Kueea System is composed of Kueea Networks. It is an abstract thing that does not physically exist. There exists only one Kueea System; do not use ‘the’ in English.
A Kueea Network is a computer network, in which every node is a Kueea Node - one that supports the required set of network services by implementation of corresponding Kueea Modules.
Modules and M-Builds
A Kueea Module is a technical document written in Kueea Module Definition Language (abbreviated as KMDL). It defines symbols – functions and data objects of various kind. Once a symbol is defined, the definition never changes (if published.)
Modules are identified by their globally unique identifier. Symbols are grouped into levels. Implementations of a module at level n contain all symbols defined by levels [0,(n] of that module.
An M-Build is an implementation of one or more modules. They are program images interpreted and executed by system software. The system is not dependent on any particular image format, although there always exists a preferred format for these images.
Each module’s goal is to standarize some specific system functionality. Modules ought to follow the KISS (Keep It Simple, Stupid) rule. They are to be narrow in scope so that their developement ends one day, the module becomes finalized and no more symbols are ever added to it. If it does not need revision, it means it’s good and can be safely used.
Having too much funcitonality in a module makes it more unstable. Stability is the most important trait every module author ought to pursue. Modules that are constantly revised are broken by design. Such modules ought to be scrapped, made obsolete, and then redesigned as new modules with a new identifier.
The scale of a module should be small enough for one person to not become mentally exhausted (burned out) while implementing it alone. There should be many implementations available that a user can choose from.
One should differentiate between a module and a software project. The module ought to be a part of the project, not the project itself. For example, if a Python interpreter were to be a module, then Python 2 and Python 3 should be different modules developed as part of the same project. They are different because the most crucial part—the parser and interpreter—are different for version 2 and for version 3. The other reason is that Python 2 is phased out in favour of 3. Keeping both 2 and 3 in the same module is counter-productive. Remember that symbols—once defined—cannot be removed from a module.
Some modules are published and standarized for the general public. Other modules may be known only to select few or be created as part of developement or a user session and have the lifetime of only few hours.
Programs and memory types
Kueea System programs are executed by an abstract computer. The processors of the computer do not matter; they are undefined. What matters, however, is the memory that the processors access.
The abstract computer is implemented as a Kueea Network. Memory of all its nodes is the memory of this abstract computer.
There are three distinct memory spaces within Kueea System.
Network (system) memory
Network memory is made of octets, each having a 192-bit address. The higher 128 bits of the address reference a node in a Kueea Network. The lower 64 bits reference an octet allocated by that node. Reference to this memory is called a handle.
In other words, each node can allocate at most 264 octets. Also note that one physical machine may function as more than one node, because the whole network is virtual along with all of its nodes.
Upon object allocation, an address range is associated with an object. Throughout the lifetime of the object, its address range does not change. The address range may be reused only after said object is deallocated.
At one point, the authors considered hardware that could reference network memory directly, but that idea was abandonded. The problem lies in that if the memory was physically at another node, fetch operation would complete after the data arrives over the network link. The CPU would not be able to execute the next instruction or be interrupted. This would introduce very long delays, which is unacceptable. Long-distance network links also introduce a bunch of other problems. The 192-bit network memory is thus entirely implemented in software.
System tasks access memory through their virtual memory. The memory space is made of bytes, which must be at least 8-bit long.
Upon calling a function and when returning from one, bytes of objects passed as parameters must have all bits above the lowest 8 cleared. The bits must also be kept cleared whenever an object is, or may be, accessible to more than one task. In other words, the bits are assumed to be cleared when loading.
The bytes are referenced by 64-bit virtual addresses. These addresses are unique to a given task. Virtual addresses are defined to map into network-memory addresses.
Current (as of 2019) CPUs reference memory with 64-bit values, of which not even all of the 64 bits are used for the address. The authors believe 264 octets is enough for any task, although some once thought 16 MiB of RAM is enough.
Actual object data resides in a machine's physical memory, i.e. the memory space at which physical (real) devices are mapped onto. Reference to this memory is called a physical address.
In practice, virtual addresses are translated by a CPU into these directly. If the referenced memory is not part of the physical memory of the machine, the reference is intercepted and dereferenced by system software.
The point of this is to write programs without thinking about or caring whether an object is physically at the current machine or at another. Physical location of an object is managed by system software. This includes transferring the data from one node to another.
Kueea System is an object-oriented system.
An object has the following traits:
- location of its data (handle and physical address),
- length of the data (in octets),
- type of the object (class),
- level of data confidentiality and other attributes.
The confidentiality level determines what kind of memory to allocate, whether to encrypt it and if the memory needs to be cleared or not. Copying data from a higher level to a lower level is a security error.
The lifetime of an object is as follows:
- A task requests the system to allocate memory for an object.
- The task gains access to the object’s memory by mapping it onto the task’s virtual memory space.
- The task invokes the object’s preconstructor; i.e. initializes the object to a safe state. (Precostructors never fail.)
- The task invokes the object’s constructor. If the constructor fails, skip to step 7.
- The object is now created.
- Tasks utilze the object.
- Tasks lose access to the object by unmapping it from the task’s virtual memory space.
- When there are no more references to the object, the system invokes the object’s destructor in a new task.
- The system deallocates the object’s memory.
This poses a question: What should the system do when a destructor fails? The preferred answer of the authors is to log the event and continue.
Classes and interfaces
Every object is an instance of some class. Classes are made of data and function members. Function members are often called methods of the class.
Data members of a class are instances of a class or octets, (The system defines only one fundamental class – an octet). Each data member is located at a predefined offset into the object; i.e. a class defines precisely how its data members are laid out in memory.
Similar to modules, classes also have levels. Higher levels add new function members to a class and may only extend the data structure of a class with new data members.
Classes have memory address alignment requirements. Data members should be arranged from longer alignment to shorter alignment. Inserting padding between subsequent members is strongly discouraged.
Classes may implement sets of members called interfaces. If the interface defines data members, the class must contain these members somewhere within its data structure and is expected to implement all of the required functions that the interface defines.
Information about classes and their interfaces is stored within special read-only objects called class descriptors.
Tasks may access this descriptor, which allows them to execute interface functions without any prior knowledge about a given object. Programs are written to either manipulate an object based its type or based on the object’s implemented set of interfaces.
In other words, run-time type information about objects is a part of the system’s ABI in order to provide system-wide virtual function functionality to every task in the system, regardless of the language a program has been written in.
Tasks are created as part of answering a query to the system. They begin at any function and finish when that function returns. A task may also fail, which is distinct from a successful return.
When a new task is created by the system, the caller task becomes the task owner of the callee. Ownership relations form a hierarchical tree structure. When a task is taken out of the tree, it becomes a detached task.
Task ownership may be transferred to another task, as long as the target task is located deeper (in the tree) than the current owner and the caller. Detached tasks are an exception - any task may become their owner.
The first task a node executes is called its boot task, which is placed at the root of the task tree.
Tasks may return a value, which other tasks can later obtain. Values returned by detached tasks are forgotten immediately.
Tasks are deleted when in detached state and have returned or failed.
Tasks access objects though their virtual memory, which is composed of three memory spaces called access contexts:
- task context, accessible only to a particular task;
- module context, accessible to all tasks of a given module; and
- kernel context, accessible only when the task is in kernel mode.
A task in kernel mode has priviledged access to the machine. What exactly does this mean depends on a particular CPU architecture.
Objects in module and kernel contexts exist regardless of tasks.
Function symbols are divided into three categories:
- task functions, which access their arguments only;
- module functions, which access objects in their module’s context; and
- kernel functions, which access objects in the kernel context.
Tasks and objects
The system assumes objects are big and complex data structures. Copies of objects are never created by the kernel.
All memory is shareable between tasks (including the stack.) The kernel’s main job is controlling access to object memory.
The core functionality of Kueea System is tasks’ ability to gain direct access to objects created by other tasks. This operation also gives access to any referenced subobjects.
When an M-Build image is loaded, an M-Build descriptor for each of implemented modules is created and the M-Build becomes destructed. Once destructed (loaded), the module's constructor may be called. If successful, the M-Build becomes constructed. Once constructed, module functions of the M-Build can be called.
Each module have a special object called a module state. The state is shared between all implementations of a module. Every constructed implementation must agree on the state.
Kueea Networks are virtual peer-to-peer mesh networks, although these networks may be composed of only one node.
Each Kueea Network is defined by its policy. It is a data object for a node; it may not be human-readable. Policies are enforced by system software automatically.
A node becomes part of a network by adhering to its policy. Part of the policy is its trust anchor. It is a set of entities whose statements all nodes must treat as true. This policy and trust is what defines a Kueea Network.
One node may be a peer in multiple Kueea Networks at the same time. Which networks are to be considered is based on who sent a message.
The goal of Kueea System is a state where every node on the Internet agrees to some universal policy, i.e. every node on the Internet is part of one big Kueea Network. This is very difficult, but the authors believe that it is doable.
Kueea Nodes may serve a particular role in the network. A node broadcasts to the network its intent to serve a role. Other nodes, upon receiving the intent, may accept it or not. Incoming connections to a node mean that the role has been accepted.
Examples of roles are: value registry, file archive, public cache, etc. Basically, these are nodes that are frequently accessed by others. Most of them are expected to have fast connections and high availability.
Resources in Kueea System are all vertices of a global graph. They are always referenced directly by their identifiers. An identifier is an opaque data object to the system.
Resources are either device-independent, in which case their identifiers are node-agnostic and do not take device or node identifiers into account; or they are device-specific, in which case the node needs to be specified.
Device-specific resources are generally limited to physical devices only.
Kueea and user sessions
Resources called kueea are entities on behalf of which tasks are executed. Kueea do not necessarily represent living beings. Think of it as a mask a human puts on when interacting with others.
User resources are collections of private kueea data. The user resource should be stored on a device one carries with oneself. It could be a pendrive or some other removable storage device. The data should never be stored on a publicly accessible storage medium.
When someone wants to use the system, the person points the system to its user resource. The system then asks the user to provide information required to access kueea credentials stored in the user resource. When the data is successfully accessed, the system requests the user to provide a system shell and select the default kueea for the session.
Shells are designed so that users may freely switch between their kueea within the same user session.
Kueea are globally unique resources, generated independently of the system and then registered with a Kueea Network in order to be recognized. Users themselves are the sole authoritative source of information about their kueea, although there is a third-party trust anchor involved. The trust anchor certifies the method of authenticating a kueea.
Authentication is generally based on asymmetric cryptography, in which case the trust anchor is needed to certifiy the kueea’s public key.
Kueea System stores files in a graph structure natively. File systems utilizing a tree structure are not used.
Files are not referenced by name. In fact, a file may have no name at all. Files are referenced by describing them with parameters. The system then searches the network for files that match the criteria.
There is a data duplication and management system. It monitors availabily of files and tries to preserve them by maintaining a state where a file is available on more than one node.
Files are assigned a preservation value. More valueable files have a higher priority and are duplicated more often. Networks decide how to assess the value of files.
File access control
Access control in Kueea System is consensus-based. Rights are determined by the policy of a network.
Files always have a public metadata document. This metadata contains access control information among other things. It is always transferred before the data proper, which might be protected.
If data of a file is unavalable locally, the node will look for it on the network. In order to successfully fetch it, the other peer must also agree on the assessment that the kueea in question may access the file.
Peers that requests files on behalf of kueea that do not have rights to said files are mailicious and are to be banned by every node in a network. Malicious peers are eliminated by denying them access to other peers.
The punishment is in that the peer becomes alone, without access to any of the resources offered by the network. If it wishes to regain access to the resources, it must follow the policy. The policy is publicly available for review and inspection. Every banned node must be informed of the rules that it broke.
If a peer does not agree with the rules in the policy, the options left are to establish a new network or look for another. Discussing a policy can only be done while within a network or out-of-band.
A node that does not follow the policy in its network effectively creates another, hidden network with some other policy. In order to become part of this hidden network, one would need to somehow obtain addresses of its hidden nodes. In other words, life is very difficult for such networks. All nodes would also have to put trust in each other for staying hidden. Discovering these nodes exposes the ones that break the rules.