Excellent points , and I think the order of operations which you propose makes sense, I did indeed start at the stratospheric level here (but I think it’s at least helpful to have that goal in mind, while we focus on the immediate next steps).
I want to drill down on a few of the questions you raise here and see if we can make some progress. Let’s start with the question of application boundaries, which is more or less equivalent to the question of identity: what is an application? I’m going to try to approach this from two angles: the perspective of the developer (and, by proxy, the user), and the perspective of the network – and then attempt to synthesize them.
The developer/user perspective
From the perspective of the developer (and, by proxy, the user), an application is simply something that they’re using Anoma for, such as sending messages to friends or colleagues (multichat), operating a city-level bartering network (multidimensional DEX), or representing a complex biome (TerraTwin). From this perspective, the only thing that matters is the application’s observable behavior: what inputs can different users enter, and what outputs can they read? In order to develop an application, a developer must have a concept of what they want to be possible, and what not. If we were to try to visualize this perspective, I think it might look like this:
From the perspective of the developer or user, the application simply is its interface: the space of inputs, outputs, and behavioral properties thereof. How state, resource logics, or other Anoma network operational details work “under the hood” doesn’t matter as long as the correct inputs and outputs are supported and behavioral properties are preserved. A user can observe nothing else.
How should applications interoperate with each other, from the perspective of the developer or user? I think we can generally say that other applications should be able to provide inputs and consume outputs in the same way a user would directly, but that the desired behavioral properties must be preserved no matter what other applications are involved. Let’s suppose that we have three applications, where Application 2 provides inputs to and consumes outputs from both applications 1 & 3. Visually, we could depict this like:
Now, the inputs and outputs of application 2, and behavioral properties thereof, may be dependent on applications 1 and 3, so the developer of application 2 must understand and incorporate them correctly. Applications 1 and 3, by contrast, should not even need to specifically know of the existence of Application 2 – there is no need to differentiate the inputs coming from and outputs going to Application 2 from those of a direct user (and no way to do so anyways).
To recap, from the perspective of the developer (and, by proxy, the user):
- An application is nothing more than an interface of possible inputs and outputs, and behavioral properties thereof. Internal details of Anoma do not matter as long as they operate in a way which preserves the desired behavior of this interface.
- Applications should be able to interoperate on the basis of inputs and outputs just as if they were users. Developers of applications which depend on other applications will need to reason about all of the inputs, outputs, and behavioral properties involved.
Now, let’s look at applications from the network perspective.
The network perspective
From the perspective of the Anoma network – the distributed network of computers which run the protocol, run controllers, solvers, etc. – there is no such thing as an application. The network only knows about state, and rules for how that state can change. Whether a particular piece of state is considered by a user to be part of application 1 or 2 is not something the network can or needs to know. We may have many kinds of state in the future (such as MRDTs), but for this post let’s just talk about state in terms of resources. Limited to that scope, the Anoma network state consists of a set of unspent resources, each of which is controlled by a single controller, and each of which is governed by a resource logic which determines under what conditions it can be consumed (and under what conditions new resources can be created). Visually, we can put each resource in a controller box:
Synthesis
Whatever inputs and outputs applications have, they must be ultimately expressed in terms of consuming or creating resources (and perhaps storing or retrieving resource-linked data). While each resource is controlled by exactly one controller, it may be a part of any number of applications (in the sense of possibly being consumed or created by application inputs, and possibly being read as part of application outputs). For example, suppose that applications 1 and 2 both may write or read R3:
This merits further exploration, but unfortunately I’m running out of time for now, so I think it’s most helpful to summarize the main takeaway here:
- Previously, e.g. in the RM specs, we’ve defined an application as the combination of a set of resource logics, a set of transaction functions (write interface), and a set of projection functions (read interface).
- I now think that this definition is slightly wrong. Specifically, I think that we should exclude the resource logics. Applications should be defined only by their read and write interfaces (these will not be exactly the same as transaction functions) and behavioral properties thereof. Rather than saying that a particular resource logic is part of a particular application, we will say whether or not a set of resources implements a particular application. This distinction may seem subtle, but I think that in conjunction with further investigation it may clear up a lot of the conceptual issues here. Application definitions, similarly, should be only in terms of inputs, outputs, and behavioral properties – we should be able to completely separate the definition of an application from potential implementations. I think considering applications in terms of desired inputs, outputs, and behavioral properties can also clarify the questions around shielding and privacy, since – fully articulated – these inputs, outputs, and properties should include reference to who is supposed to know (or not know) what.
- I see several immediate next steps here, such as:
a. Trying to figure out more precisely what the types are (of inputs, outputs, and behavioral properties), and figuring out how these would map to transaction functions and state queries.
b. Figuring out how this relates to the object model in discussion.