A village network protocol

Posted in hygiene p2p protocol network crm privacy f2f community

What would truly peer-to-peer CRM backend look like? And at that, once that respected the right of the "customer" to choose how it wants to represent itself in the context?

Perhaps by Modeling the network on how villages treat strangers and their own, and how you would go about interacting with them.

Here's an initial stab at describing what such a meta-protocol could look like.


A subjective structure where the thing being described is the thing that described it.
A particular perception of an individual by an entity in the network.
Data structure containing details about a user. May or may not be public.
A group of individuals acknowledging each other as part of a group, and who share views on users.
A member of a group of locals, from the shared perspective of an individual and another local.
The individuals making up a group of locals, from the perspective of a local.
A user as percieved by a group of locals.
All users that may speak to the locals, from the perspective of a local. To be shared among locals.
Userspec created by a local describing a user. To be shared among locals.
An individual or any derived representation of it (user, stranger, local).
An entity coupled with connection information
Content address
SHA256 sum of arbitrary content
Key setup
May be an individual key, or a specification describing how to generate keys for a particular relation.


The individuals

Are free to have their own opinion of what they are.

When interacting with others, they are free to choose what they say about what they are.

An individual initially defines itself in the network.

The users

A user is a view of an individual as defined by one or more other individuals.

It may be how an individual presents itself to an particular individual or a group.

It may also be how an individual or a group presents another individual to itself.

The locals

Locals are a group of individuals who wish to share a view of themselves and prejudice about others.

An individual will not be treated as a local unless it and its local counterpart considers it a local.

Locals may acknowledge strangers with or without proof.

If one local changes opinion about a stranger, all locals should change their opinon to the same.

If one local excludes a stranger, all locals should exclude the stranger.

You can't keep secrets in a village. If someone says something to another local, it must assume all locals will get to know what was said.

The strangers

A stranger is a user that's not considered local by a group of locals.

A stranger may not speak to a local until the local has decided it can.

If a stranger may speak to one local, it may speak all locals.


The individual_id is the identifier of an individual consists of the content address of some basic public data about the entity registering itself. The individual_id is immutable.

Any local will refer to another local by its individual_id.

A user_id is the content address of an individual_id together with the content address of some basic data describing the perception of the individual.

Locals describe stranger by a pair of individual_id and user_id. Let us call this stranger_id. The stranger_id is immutable.

The data represented by the user_id in a stranger_id is visible to locals, and may or may not be public.

State description

A user keeps a state towards other entities consisting of the following content-addresses, in the given order:

  1. Previous state
  2. Userspec

A local keeps a state towards its locals consisting of the following content-addresses, in the given order.

  1. Previous state
  2. Userspec
  3. Localslist
  4. Locals state
  5. Strangerslist
  6. Strangers state

The state is represented by the content address of the concatenation of these content-addresses, in the given order.

Any state change will be signed by the key resolvable through the individual_id.

Previous state

The content address of the previous state. Will be 0 in the first state.


The individual as it wants to be perceived in the current context. There is no guarantee that the individual will be viewed in this way by others.


A lexiographically ordered array of individual_id that define the individuals in a group of locals.

All locals must keep this list in the same state.

Locals state

A local's last recorded state of each of the locals, in the same order as Localslist.

The recorded state is the same content address as in the state description section above.

All locals must strive to keep this in the same state.


A lexiographically ordered pointer array representing a local's opinion of which users that can communicate with locals. [1]

Combination of stranger_id and a vote on the specific user.

The vote can be in one of three states:

  • Value 0, meaning local has acknowledged the user, explicitly or by following other locals. We call this state "deferred."
  • Value -1, meaning a local has vetoed the user. We call this state "vetoed."
  • Any other value, which is the content-address of the proof accepted by the local. [2] We call this state "accepted."

Typically, the initial vote value is 0. The value may change at any time, but may never change back to 0 once set to another value.

A user that is part of the list, but not vetoed, is referred to as "acknowledged."

The Strangerslist state may be differ between locals, but they should strive to keep it the same.

Strangers state

The local's version of the current user state of the strangers, in the same order as the Strangerlist.

The Strangers state may differ between locals, but they should strive to keep it the same.

Behavior of locals

A local may announce itself as active or passive. This should be part of the Userspec in the locals context.

Specifically, this affects the way it "votes" on strangers. A passive local:

  • Will always veto a user if at least one active local has vetoed it.
  • Will always accept a user if all active locals have accepted it. [3]

Typically, a passive local will be a bot, for example an always-online node that guarantees availability of the locals so users can request state changes.

There must be at least two active locals in any group of locals.

Veto dissent

If a local vetoes a stranger, then all locals should cut communication with that stranger.

Vetoes should be adopted by all locals.

If, however, other locals consider the veto to be issued in error, there are two possible outcomes:

  1. The vetoing local(s) abandon(s) the veto. [4]
  2. The vetoing individual(s) is/are excluded by the locals.


Any entity needs to define and announce itself as a peer in order to be available on the network.

A "peer" is the coupling of network connection information to an individual_id.


Peers are kept in a DHT.

Peers must be discoverable by their locals affiliation. [5]


Users open single-request connections to other users to annonunce, look up and prune peers.

Users may request state changes for themselves, or relay such requests for other users.


Locals keep open connections (streams) with each other.

Locals continually exchange state changes.

Locals should be able to audit the chain of state changes of other locals.

Between locals and users

Strangers acknowledged by locals open single-request connections to a local to announce state changes.

Locals may open single-request connections to a user to announce a change to the state of the Userspec of a stranger. [6]

Individuals are free to deny connections from non-locals, for example if the entity has been sending garbage requests. The implementation of such sanctions is deferred to the application layer.


An individual may keep content totally private on the network.

A user may keep different encryption keys for different contexts.

If a stranger shares a key setup with a local, that setup will be shared among all locals. A local will expect to be able to communicate with a strangerr using this key setup.

The stranger must be able to change the key setup towards locals.

The locals may be able to change the key setup towards a stranger.

The protocol should allow anything from simple symmetric key exchanges to complex forward/backward secrecy schemes.

[1]Insert in this sorted list will face scaling issues when locals need to acknowledge a lot of users. The lists can be split into buckets, either statically (for example two-byte prefixes) or dynamically after crossing a certain threshold. It should not be necessary to store empty buckets.
[2]This proof may map to what's commonly known as kyc information.
[3]Perhaps with the further limitation that all active users must have accepted with the same proof. Otherwise, how will the passive local choose which proof to accept.
[4]Observe that since the vote state cannot change back to 0, "cancelling" the veto can only be done by adding proof.
[5]What exactly uniquely identifies a group of locals on the network in such a way that it cannot be hi-jacked or spoofed still needs to be thought through. Perhaps it can be a combination of a specific name with a signature from the "founders;" the first (two or more) locals in it.
[6]A use-case here would be where the locals make a change for the user due to an out-of-band request from the user. This is not the Strangerspec; it is the user's current Userspec for the given context. Of course, it's up to the user to accept the change. It may in turn request a new state change to the locals to revert it.