Apian Peer Architecture


⬡ Start with the simplest data model that can possibly represent your app.
  (If it were a paper game, what would the board, pieces and scorepads be like?)
⬡ This is your CORE STATE
  It's ok for everything to be able to see it, but NOTHING CAN CHANGE IT.
⬡ ...Except CORE LOGIC.
   which is the only code allowed to update the Core State.
⬡ Core Logic and Core State make up the APP CORE.
  The idea is for pre-defined, high-level, application-domain directives to be sent to the AppCore and for the Core Logic to interpret them and make the appropriate low-level changes to the state data.
  And this is the ONLY way to modify the Core State.
Some AppCore rules:
⬡ State can be seen and queried by everyone.
⬡ State can ONLY be modified via external commands.
⬡ State must be serializable, restorable, and hashable.
⬡ Logic must be deterministic. Cannot contain any stochastic code.
An AppCore instance contains all of the rules, logic, and state to perform the fundamental work of the application, but that's clearly not enough to be a standalone consumer product.
   We're going to refer to the rest simply as the APPLICATION CODE.
⬡ It handles front-end tasks like rendering the CoreState for users.
⬡ As well as collecting user input.
⬡ As well as collecting user input - which is then sent to the AppCore.
As mentioned earlier, random behavior is not allowed in the AppCore.
So any component with randomness - like an AI - has to live in the Application Code.
This is actually pretty cool, since now the AI and User actions work exactly the same way.
Sending commands directly to the AppCore works pretty well for a single-user app.
But that's not what we're trying to do.
Which brings us to a new component: Apian
An Apian instance is always paired with an AppCore instance.
And an important thing to know about it is that it is functionally a proxy...
for a virtual "Apian Group" object...
made up of it and the Apian instances of other peers.
Apian defines 3 types of messages that "wrap" application directives:
  Commands - tell the AppCore to apply an application directive to the Core State.
  Requests - from the Application Code *ask* that a directive become a Command.
  Observations - are similar to Requests, but originate from the AppCore itself.
The principal function of the Apian Group object is to decide which Requests and Observations get promoted to Commands and applied to the Core State
...and in what order.

So putting it all together...
Application Code collects input and creates an ApianRequest
and sends it to the local Apian instance which distributes it to the group
which agrees that it should be a command
which is then applied to the AppCore.
In much the same way, a remote peer can send a Request to Apian.
Which the Apian group might promote to a Command.
Which will be allied to everyone's App Core.
Sorry! This is as far as I've gotten for now...