We need a type system with algebraic data types to describe messages, both on the network layer sent over the wire and messages stored in the network, with versioned messages in both cases.
We also need a binary encoding for the messages.
Implementations need a bidirectional mapping for the binary encoding from/to their native types with validation/type checking to ensure correctness of decoded messages.
This seems like an odd requirement. Object typing and algebraic data types are similar where typically objects are open and ML style sum types are closed. However object typing can even enforce closed relations see Scala’s sealed keyword
In particular if we have
Type my-type = a | b | c
We can emulate this with
Object my-type
Object a inherits my-type
Object b inherits my-type
Object c inherits my-type
Getting the same effect without any requirements of ADTs being necessary