The Entity Core Protocol: Wire Format, Dispatch, and Capability Verification
We present the Entity Core Protocol: a minimal protocol for distributed information systems defined by six irreducible primitives — Entity, Identity, Tree, Emit, Execution, and Peer. The protocol specifies a wire format (Entity Canonical Form over deterministic CBOR), two message types (EXECUTE and EXECUTE_RESPONSE), tree-based handler dispatch, a two-round-trip connection handshake, four-dimensional capability grants with cryptographic attenuation, and a structural type system of 14 bootstrap types that describe themselves. The protocol was found by alternating construction and reduction — building mechanisms to face each next concern, then removing what the entity model could absorb, until the cycle exhausted itself. The spec continues to refine operationally, but the structural reductive moves are done. The protocol shrank while the type system grew. A layered system-extension set composes through the same six primitives without modifying the core. Three independent implementations (Go, Python, Rust) validate cross-platform conformance; separately, peers generated from the specification into dozens of languages pass the same core-profile gate, which tests the specification’s precision rather than adding independent implementations. No interaction has yet been identified that requires a third message type; if one is, the closure claim is wrong.
1. Introduction
This paper presents the Entity Core Protocol: a protocol for distributed information systems defined by six primitives.
The six primitives are:
- Entity: the typed data unit —
{type, data} - Identity: content-derived hash — same content, same identity, everywhere
- Tree: mutable namespace — path hash bindings over immutable content
- Emit: the atomic state change — Store (content) and Bind (tree), each independently observable
- Execution: typed dispatch —
EXECUTEandEXECUTE_RESPONSE - Peer: the participant — identity, capabilities, connection
These six are irreducible. A reducibility analysis on the resulting protocol shows that removing any one primitive loses expressiveness — you do not get the system. The structure of the primitives is the system.
The paper presents them in the order the spec develops them — foundations, types, protocol messages, connection, capabilities, handlers — then examines the properties that arise and the extension architecture that composes on top.
The cycle that produced the spec: mechanisms were built to face each next concern, then removed where the entity model could absorb them, then built again, then reduced again, until the cycle stopped finding things to remove. The protocol shrank while the type system grew. What remains is minimal — there is nothing left to remove. The architectural methodology that drove this cycle — simplicity, convergence as the stopping rule, mathematical structure where it reaches, considered convention where it does not — is described in The Entity System and applied here as the lens through which the spec was assembled.
2. Background
Just enough to situate the protocol; the full landscape is in Convergent Evolution.
2.1. Content Addressing
Git, IPFS, Nix: content-derived identity in specific domains (version control, distribution, builds). Each gets immutability, deduplication, verification. None carries type information with the data. None generalizes to a protocol with dispatch or capabilities.
2.2. Typed Protocols
Protobuf, Cap’n Proto, gRPC, Thrift: typed messages, but schemas are external — compiled from definition files, not carried with the data. The data doesn’t know its own type. No content addressing.
2.3. Capability Systems
Macaroons, UCAN, Biscuit: authorization with delegation and attenuation. Not integrated with content addressing or typed data. Authorization as a separate subsystem attached to other protocols.
2.4. Distributed File Systems
Plan 9/9P, Inferno/Styx: everything as files, namespace composition. Untyped bytes on the wire. No content addressing. Per-connection auth (which breaks when data is mobile across connections).
2.5. What’s Missing
Existing systems implement subsets of the six primitives. Content-addressing systems lack types. Typed protocols lack content addressing. Capability systems are bolted on. No existing system integrates all six as a coherent minimal protocol. The entity core protocol does.
3. Foundations
The structures the rest of the protocol builds on.
3.1. Entity
The fundamental data unit:
Entity := { type: string, data: any, content_hash: bytes }
Type is constitutive — an entity without a type is not an entity. This distinguishes it from a byte blob (Git), a codec-tagged block (IPFS), or an untyped record. The type is part of the thing, not metadata about it.
3.2. Content Hash
content_hash(entity) = format_code || SHA256(ECF_encode(type, data))
Input: {type, data} only — the hash itself is not hashed. ECF = Entity Canonical Form: deterministic CBOR (RFC 8949 §4.2). Same {type, data} same hash, everywhere, always. Different type different hash even with identical data. Identity is intrinsic.
Format code byte pins both the encoding version and hash algorithm. Current: 0x00 = ECFv1-SHA-256, 33 bytes total.
Consequences of content-derived identity:
- Immutability: changing content changes identity — it’s a new entity
- Deduplication: same content stored once, referenced everywhere
- Verification: anyone with the hash can verify the content
- Convergence: peers with the same hash at the same path have converged
3.3. Entity Canonical Form (ECF)
Deterministic CBOR encoding rules ensuring identical bytes for identical data:
- Map keys sorted by encoded byte length, then lexicographically
- Minimal integer encoding; definite lengths only
- Shortest float preserving value; no duplicate map keys
- All field values preserved (entity fidelity)
3.4. URI and Path Model
URI := "entity://" peer_id "/" path
All paths are peer-namespaced. Short-form URIs (no prefix) scope to the local peer. Paths are UTF-8; / separates segments; * is reserved for capability patterns.
Dispatch routing: a peer processes only requests targeting itself. Cross-peer forwarding is provided by extension (relay), not core dispatch.
3.5. Identity
PeerID := Base58(key_type || hash_type || SHA256(public_key))
Ed25519 key pairs. Peer identity is derived from the public key — content-addressed identity applied to participants, not just data.
3.6. Storage: The Two Address Spaces
Content Store: hash → entity (immutable, deduplicated)
Entity Tree: path → hash (mutable, namespace)
The content store is “what things are.” Append-only. The entity tree is “what things are called right now.” Bindings change.
These two spaces are forced: if identity = content, content can’t change, but you still need “the current version.” The tree is that mutable layer. Together they give versioning by construction — rebinding a path preserves the old entity (it still exists by hash).
The tree is a logical namespace (flat path hash mapping), not a filesystem. A path may be simultaneously bound to an entity and serve as a prefix for child paths.
3.7. Envelope Structure
Envelope := { root: entity, included: map<hash, entity> }
Root: the primary entity. Included: flat map of referenced entities. Sender controls materialization depth. Same structure for wire and storage. No re-encoding at boundaries.
3.8. Entity Fidelity
Implementations MUST:
- Validate hash on receipt (recompute from
{type, data}, compare) - Trust validated hash for all subsequent operations
- Store and forward original bytes (no re-serialization)
- Preserve unknown fields (forward compatibility)
3.9. Namespace Design
Two layers: structural (dispatch, capability scoping, self-description) and naming (paths, domain grouping, conventions). Structural properties are mathematical — would be rediscovered by any implementation. Naming is design within the space structure leaves open. The sole structurally fixed path: system/protocol/connect (connection handler). All other paths communicated through initial capability grants.
4. Type System
Types are entities; entities carry types.
4.1. Type Definition
Every type is an entity of type system/type:
system/type := {
name: type_name,
extends: type_name?,
fields: map<string, field-spec>?,
layout: [string]?,
type_params: [string]?,
type_args: map<string, type_name>?
}
Types stored at system/type/{type_name} in the entity tree. Types are entities. Entities carry types. This recurses.
4.2. Bootstrap Types
The type system is seeded by fourteen bootstrap types: eight primitives (string, bytes, uint, int, float, bool, null, any) and six structural types — system/hash, the meta-type system/type, system/type/field-spec, system/tree/path, system/type/name, and system/identity/peer-id. The structural root entity ({type, data}) is built from them.
These fourteen are sufficient to describe all types — including themselves. system/type is itself a system/type. This is a fixed point.
Self-description is not a designed feature. It’s what happens when everything is entities: descriptions of entities must also be entities, described by the same type mechanism. The recursion bottoms out at the bootstrap types.
The protocol’s own constructs — handlers, capability tokens, grant entries, envelopes, execute and execute_response, signatures, operational state, errors — are themselves entity types, defined from the bootstrap set rather than added to it.
4.3. Structural Typing
Types describe shape: fields, field types, optionality. Validation is structural: does this entity match its type definition? Single inheritance via extends. Open types preserve unknown fields. Generics via type_params/type_args.
4.4. Types Cross the Wire
Unlike Protobuf (schemas compiled from .proto files) or Inferno (bytes on the wire, types only in application code), entity types travel with the data. The protocol is typed end-to-end: no type gap at protocol boundaries. A handler receives typed params, returns typed results. The tree stores typed entities. The wire carries typed entities.
5. Protocol Messages
The protocol has two message types.
5.1. EXECUTE
The request: dispatch typed parameters to a handler.
system/protocol/execute := {
request_id, uri, operation, resource?, params,
author, capability, deliver_to?, bounds?
}
Every interaction is an EXECUTE: queries, mutations, subscriptions, connection setup. The operation vocabulary is unbounded — any handler can define any operation. The message structure is fixed.
5.2. EXECUTE_RESPONSE
The response: deliver a result entity to the caller.
system/protocol/execute_response := {
request_id, uri, result, status, deliver_to?
}
5.3. Why Two Suffices
Every distributed interaction is “I want something done” + “here is the result.” The “something done” is parameterized by handler, operation, and resource. There is no interaction pattern that requires a structurally different message.
Query? EXECUTE uri: system/tree, op: get
Create? EXECUTE uri: system/tree, op: put
Subscribe? EXECUTE uri: system/subscription, op: subscribe
Connect? EXECUTE uri: system/protocol/connect, op: hello
The vocabulary of operations is unbounded. The message structure is not.
5.4. Why Two Messages
The reduction to two message types was discovered during relay implementation. Earlier drafts carried a separate message for each kind of interaction — query and response, subscribe and event, execute with its stream/complete/error replies, the connection and identity exchanges — on the order of a dozen, and shrinking draft to draft. A relay forwards operations between peers. When building it, every message type was wrapped inside an EXECUTE for forwarding. The wrapping was lossless — a relay doesn’t need type-specific logic.
If a generic forwarder can handle all interactions with one message structure, the separate message types are syntactic sugar. The earlier messages (query, subscribe, and the rest) moved into the handler layer as operations. The protocol boundary compressed; the operation vocabulary expanded.
The computational significance of EXECUTE — its structural correspondence to beta-reduction in lambda calculus — is examined in The Entity Church Architecture. The deeper conceptual reformulation this wire reduction expressed — a shift in what a message is — is developed in §The Relay Insight below.
6. Connection Establishment
How two peers connect.
6.1. Flow
The mandatory handshake is two EXECUTE round-trips:
- Initiator
hello(peer identity, protocol version, capabilities) Responderhelloresponse (responder identity, negotiated params) - Initiator
authenticate(signed challenge) Responderauthenticateresponse (verified; carries the initial capability grant)
The initial capability grant rides back in the authenticate response, not a separate exchange. The protocol also defines a symmetric third leg — the responder authenticating back to the initiator — but it is optional and reachability-gated: it applies only when the initiator is itself a serving peer the responder can later call into, and no current implementation sends it. A client-style initiator (browser, CLI, conformance harness) completes the handshake on the first two round-trips alone.
Connection uses EXECUTE with pre-authorization at system/protocol/connect. No special connection protocol — the same dispatch mechanism used for everything else.
6.2. Pre-Authorization
Before authentication completes, only system/protocol/connect is reachable. The handler is pre-authorized: no capability required. After authentication, the initial capability grant defines what the connecting peer can access. Everything is communicated through grants.
6.3. Initial Capability Delivery
The initial grant tells the connecting peer:
- Which handlers it can reach (handler patterns)
- Which data it can access (resource patterns)
- Which operations it can perform
- Which peers it can interact with
Paths in the grants communicate the peer’s actual namespace layout. Peers that follow naming conventions get predictable trees; peers that diverge remain conformant — they communicate their paths through grants.
7. Capability System
Authorization integrated with the protocol.
7.1. Four-Dimensional Grants
Each capability grant specifies scope on four dimensions:
grant_entry := {
handlers: scope, -- which handlers (path patterns)
resources: scope, -- which data paths (path patterns)
operations: scope, -- which operations
peers: scope -- which remote peers
}
scope := { include: [pattern], exclude: [pattern]? }
All four dimensions must match in a single grant (conjunctive). Uniform pattern matching across all dimensions.
7.2. Attenuation by Construction
Child grant parent grant on all four dimensions. Enforced by cryptographic chain: each child references its parent by content hash. Cannot insert or modify chain links without breaking hashes. Capabilities can only be narrowed, never amplified.
Delegation caveats: max_depth (default 64), max_ttl, no_delegation. The chain is a content-addressed linked list — each token is an entity, verifiable independently.
7.3. Verification Algorithm
On each EXECUTE:
- Verify capability signature chain (each link signed by granter)
- Check handler scope (does the grant cover this handler path?)
- Check operation scope (does the grant cover this operation?)
- Check resource scope (does the grant cover the target resource?)
- Check peer scope (does the grant cover this peer?)
- Verify delegation chain (parent child attenuation valid?)
Root capability granter must be the local peer.
7.4. Two-Level Enforcement
Level 1 (dispatch): before the handler runs, check all four dimensions. Level 2 (handler): handler re-checks capability against specific paths. Defense in depth: dispatch catches broad violations, handler catches specific.
7.5. Per-Message Authorization
Each EXECUTE carries its own capability token. No session state. Content-addressed entities are self-verifying — they can be relayed, stored, and forwarded across connections. Per-connection auth breaks when entities are mobile.
8. Handler Model
How handlers register, dispatch, and execute.
8.1. Registration
Handlers are entities registered at tree paths: system/handler/{pattern}. A handler entity describes: which path prefix it serves, what operations it supports, its interface type (input/output types per operation). Handler registration and unregistration are themselves EXECUTE operations to the system/handler handler.
8.2. System Handlers
Four core handlers are mandatory:
system/tree: entity storage —get,put,delete,listsystem/handler: handler lifecycle —register,unregistersystem/capability: capability management —request,revoke,configure,delegatesystem/protocol/connect: peer connection —hello,authenticate
A fifth handler, system/type (type validation — validate), is conditional: a peer registers it when it supports type validation, and omits it otherwise.
These four plus the infrastructure they operate on (entity structure, content store, tree, emit pathway) are the core protocol. Everything else — including all extensions — is handler registrations.
8.3. Path Dispatch
EXECUTE arrives with a URI. Dispatch finds the handler with the longest matching prefix:
EXECUTE uri: local/files/home/doc.txt
→ longest matching handler prefix: local/files
→ handler-relative path: home/doc.txt
→ handler executes with context
The tree is the dispatch table. No separate routing mechanism. Path simultaneously serves as: name (human-readable address), dispatch key (which handler), and scope boundary (capability checking).
8.4. Handler Freedom
The protocol imposes almost nothing on handler implementations. A handler receives typed parameters and returns typed results. What happens inside is unconstrained: call a database, read a file, invoke an AI model, do nothing. Domain semantics live in handlers. The protocol provides: dispatch, capability checking, typed interface. The handler provides: everything domain-specific.
9. The Emit Pathway
The atomic operation of the protocol. Every state change is this.
Emit is two coupled operations on distinct primitives, each independently observable:
- Store: entity enters the content store (hash entity, immutable — the Identity axis).
- Bind: tree binding updates (path hash, mutable — the Tree axis).
Both happen atomically; each produces an event when it does real work. Re-putting identical content is a no-op at the Identity axis; re-binding to the same hash is a no-op at the Tree axis. The Store event and Bind event are independently observable — consumers register on either or both, depending on which axis they care about.
This is the crossing point between the two address spaces. An entity is born eternal (content store, immutable, by hash). A binding gives it a temporal name (tree, mutable, path hash). Events make the change observable along either axis.
Every state change — handler result, tree modification, entity creation — is a sequence of emit pathway crossings. This is irreducible.
Properties that fall out:
- Versioning by construction: rebinding preserves the old entity
- Audit trail: content store is append-only; history is cryptographic
- Event sourcing: emit events form a complete log of state changes
- Extension integration: extensions consume either or both events, depending on what they observe
Consumer coordination — how multiple extensions compose over shared emit surfaces, ordering rules, cascade depth, convergence classes, well-behaved-consumer patterns — is specified in the SYSTEM-COMPOSITION layer, not in the core protocol. The core protocol specifies the primitive; SYSTEM-COMPOSITION specifies how consumers compose over it.
10. The Extension Architecture
The core protocol is complete and useful alone. Extensions compose on top using the same mechanisms: handler registration, typed dispatch, capability checking, emit pathway events. Extensions don’t modify the core — they add handler operations at new path prefixes. The protocol boundary is unchanged.
10.1. How Extensions Work
An extension registers a handler at a system/* path prefix, defines types for its operations, and optionally consumes emit pathway events. It uses the same EXECUTE dispatch, the same capability model, the same entity tree. There is no extension API separate from the protocol itself.
10.2. The Extension Landscape
The system-extension layer is stratified. The substrate-bridge extensions are the structural set that carries the core primitives up to where applications are built:
system/tree(extended): bulk operations — snapshot, diff, merge, extractsystem/type: value-level constraints and type analysissystem/content: content chunking, deduplication, manifests; consumption-format descriptors as tags over blobs (proposed)system/inbox: async cross-peer message deliverysystem/subscription: reactive event streams on tree changessystem/continuation: durable execution chaining, cross-peer workflowsystem/compute: expressions, derived entities, reactive evaluationsystem/query: secondary indexes and compositional queriessystem/revision: version DAG, three-way merge, cross-peer syncsystem/history: per-path transitions, audit, rollbacksystem/clock: system time — wall-clock plus logical/vector references
Alongside the substrate-bridge set, three further categories are recognized but distinct in role. Operational extensions — identity management, attestation, quorum, role-based authority, group membership, network connectivity, peer discovery, relay — provide the operational semantics any deployed multi-peer system needs; they are not part of the substrate-bridge set that carries the core toward application development. First-pass-grounding extensions — currently system/transaction — frame major CS concepts the community will expect, held loosely as anti-fragmentation work. Exploratory extensions — currently system/durability — preserve reference designs after a retraction or before a driver is identified.
The dependency graph within the substrate-bridge set is sparse. Most extensions depend only on core. Common dependencies include subscription on inbox (delivery mechanism) and revision on tree extended (snapshot/diff/merge). Everything else composes through the handler interface and emit pathway independently.
Four extensions consume emit events: subscription (pattern-matched notifications), history (transition recording), compute (reactive re-evaluation), and query (index maintenance). They hook into the same event independently — no coordination required.
10.3. Composability
The extension architecture is evidence that the core protocol is compositional: a broad range of distributed system concerns (async messaging, event streaming, content distribution, computation, time, synchronization) all compose through the same six primitives. No extension requires modifying the core protocol or adding new message types. The protocol boundary absorbs new functionality through handler registration and type definition alone.
11. The Reduction
The protocol was assembled by alternating construction and reduction: mechanisms were built to face each next concern, then removed where the entity model could absorb them, repeatedly, until the cycle stopped finding things to remove. The principles below describe the architectural methodology that ran the cycle; the named cycles after that locate where each major reductive move happened; the catalogs of what was removed and what was added show the shape at the level of specific spec changes. The relay insight, treated separately at the end of this section, was the structurally most consequential single move.
11.1. Architectural Methodology
The cycle was guided by a small set of design values:
- Simplicity. Every mechanism in the protocol must justify its presence. A mechanism that another already covers does not stay — and the reductive pass is where this is forced.
- Convergence as the stopping rule. Construction stops introducing new mechanisms and reduction stops removing them. The result is then tested, verified, and security-patched until stable.
- Mathematical principles where they reach; considered convention where they do not. Where the structure is determined by mathematics — content addressing, deterministic encoding, hash-derived identity, the dispatch primitive — the spec follows the math. Where it is not, the spec records the convention and marks it as such.
- The protocol layer settles so layers above it can. Extensions, application architecture, and user-space sit on top; if the protocol underneath them keeps shifting, they cannot stabilise. Running this layer to convergence is what makes those layers tractable.
Counted decision histories are the wrong instrument here. What matters is whether the cycle converges and whether what remains can no longer be simplified. The cycles that follow show the structurally significant moves; the system-level statement of these principles is in The Entity System.
11.2. Cycles That Produced This Protocol
Each cycle is anchored in a specific review or implementation experience that exposed a redundancy, not in a counted decision tally. The structurally significant cycles directly shaping the spec presented in this paper:
The substrate leap. The protocol began as the distributed-substrate piece of an earlier entity-centric tool — a network-and-host visualization tool whose unified-entity refactor needed entities to be coherent across peers. The work crossed from “an application’s entity model” into “a distributed substrate’s entity model”; the leap from local refactor into protocol design produced the first version of the spec.
The relay insight. Review of a system/relay extension exposed that the protocol’s distinct message types (QUERY, EXECUTE, SUBSCRIBE, and others) were artificial: a generic relay carried all of them as EXECUTE with entity payloads. §The Relay Insight below traces it and the reformulation it forced.
The wire reduction. The previous insight, conceptual at first, materialized at the wire: the protocol shrank to two message types — system/protocol/execute and system/protocol/execute/response. Every operation (queries, subscriptions, computation, bootstrap) became a typed EXECUTE dispatched to a handler by URI path. The two-message protocol presented in §Protocol Messages is the surviving form.
The capability invariant. Multiple competing interpretations of capability-chain semantics collapsed into a single three-slot invariant: Root (resource owner), Grantee (EXECUTE author), In-chain Granters (attenuators). The trigger was a class of cross-peer capability bugs the running implementations surfaced. The resulting three-slot model is the structure presented in §Capability System.
These are not the only cycles, but they are the structurally significant moves. Each is triggered by an implementation or review experience that exposed a redundancy; each removal feeds the next cycle’s construction. The full project sequence is recorded in working notes.
11.3. What Was Removed
- Separate local/wire code paths unified model (everything through protocol)
- Inline fields entity references (author, signature, bounds = entities)
- Handler list operation tree data (handlers are entities in the tree)
- Namespace scoping machinery tree structure alone (the tree is the scope)
- Distinct message types one dispatch primitive (the wire reduction, a dozen-odd message types down to two)
- Special-case APIs entity operations (everything is an entity)
- Namespace-scoped indexes flat tree with capability filtering
- Multiple capability-chain interpretations one three-slot invariant
11.4. What Was Added
- Path type, type name type (paths and type names as first-class entities)
- Resource field on
EXECUTE(making operation targets explicit) - Operational state types (peer state visible as entities)
- Handler interface type (external discovery contract)
11.5. The Pattern
Removals are structural: mechanisms are replaced by the entity model itself. Additions are types: the type system grows to cover what mechanisms used to do. The protocol shrinks while the type system grows.
This is the signature of reduction to a single substance. When you find that a mechanism can be expressed as entity data dispatched through handlers, the mechanism is redundant. What remains after all such reductions is the irreducible core: the six primitives.
11.6. Cost Asymmetry
Adding a pattern now (during specification) costs one spec change. Adding a pattern after deployment costs coordinated migration across all implementations, users, and deployed systems. This asymmetry incentivized aggressive pre-release reduction: it was cheaper to remove now and discover the consequences than to leave complexity in and remove it later. The cycle’s pre-release intensity is a direct consequence.
11.7. The Relay Insight
The relay insight was the most consequential single move in the whole cycle. Its mechanism is the one traced in §Why Two Messages — a generic relay forwards every message by wrapping it in one EXECUTE, which makes the distinct message types syntactic sugar over a single dispatch. Its consequence went deeper than the wire: a different idea of what crosses it.
The protocol’s framing changed accordingly. It is not messages that carry entities — it is entities that manifest in peer contexts. An entity arrives, its type determines what happens, and that is the entire computational model. Message types collapsed into entity types; dispatch collapsed into handler lookup by URI path; the protocol’s surface area dropped sharply.
The wire-level collapse to two message types followed in a later cycle, once the implications were worked through across the extension landscape. EXECUTE and EXECUTE_RESPONSE, presented in §Protocol Messages, are the operational form of this reformulation.
12. Properties and Emergent Structures
What arises from the six primitives without being designed in.
12.1. Emergent Properties
- MVCC: content addressing = version column. Rebinding a path creates a new version; the old entity still exists by hash. You can’t opt out of versioning with immutable content + mutable bindings.
- Relational structure: typed records with hash references form relations. Entities are rows; types are tables; hashes are primary keys.
- Self-description: types describe types. The protocol describes itself in its own terms. This closes at the bootstrap types — a fixed point. (The computational implications of self-description — meta-circular evaluation, comparison to homoiconicity — are examined in The Entity Church Architecture.)
- Audit trail: content store is append-only. Emit events form a log. History is cryptographic (hash chains, verifiable).
- Convergence detection: peers with the same hash at the same path have provably converged, without coordination protocol overhead.
Additional computational structures emerge when the extension architecture is considered: actor model (inbox + continuation), CPS (EXECUTE as continuation), reactive cascades (subscription + emit). These are examined in The Entity Church Architecture.
12.2. Stability Under Evolution
Wire format: unchanged throughout the type system’s expansion. Entity structure: unchanged. Envelope structure: unchanged. Two-message model: unchanged. What changed: type definitions, handler conventions, capability fields. The protocol is stable. The type system grows. Evolution happens at the type level, not the protocol level. This separation is itself a property of the six primitives — the protocol is the primitives; the type system is extensible within them.
13. Implementation and Evaluation
13.1. Three Implementations
All three are at conformance parity on the normative surface. They are distinguished by the role each plays in the validation loop and by their secondary targets, not by completeness.
- Go
-
Hosts
validate-peer, the cross-implementation validation harness; the other two run against it. Go’s tooling discipline keeps the reference behavior clean. - Python
- Independent stack reading the same spec; surfaces ambiguities the other two would miss.
- Rust
- Targets performance and portability.
The three are not independent attempts at the same target. They are the operational loop through which the specification itself is refined — the methodology that has kept this spec converging as it has matured.
13.2. The Development Loop
The spec is the language-agnostic invariant; the three implementations are its validators. The operational cycle:
- Spec refinement. A change is proposed in the architecture specification, written in language-neutral terms — wire formats, algorithm pseudocode, normative MUST/SHOULD/MAY clauses, type shapes, dispatch semantics — never in language-specific constructs.
- Cross-peer implementation. All three peers attempt to implement the refinement. None is “the reference”; the spec is the reference. The implementations are validators of the spec, not authorities over it.
- Validation testing. The implementations are tested for cross-peer conformance: same entity same hash everywhere; same EXECUTE same handler dispatch everywhere; same capability chain same verification outcome everywhere. This began as live testing — the implementations run against each other and disagreement surfaces at runtime — and has since been joined by byte-pinned test-vector corpora, so a conformance claim can be checked against captured state rather than only against a running peer.
- Feedback to architecture. When implementations diverge, one of three things is true: the spec was ambiguous (and is tightened), one implementation got it wrong (and is corrected), or the model itself has an unsoundness (which triggers a new reductive cycle). The first two are common; the third has been the trigger for several of the major cycles named in §The Reduction above.
- Convergence. When all three implementations agree on the conformance surface and no spec ambiguity remains, the refinement lands.
Three implementations rather than two. Two implementations can rationalize their differences against each other — “maybe both readings of the spec are reasonable; let’s pick one and move on.” Three cannot. When three diverge, at least one is unambiguously wrong, which pushes the question back to the spec rather than letting the implementations negotiate. Three also surfaces accidental homography (same word used for different things) mechanically: when two peers agree and the third does not, the spec word that allowed the disagreement is the one to fix.
13.3. Generating Peers From the Specification
The three implementations answer whether careful people reading the same document arrive at the same bytes. A second exercise asks a different question: whether the specification is precise enough that a peer can be derived from it mechanically, into a language nobody wrote the specification with in mind.
A generator takes the specification and emits a complete core-protocol peer for a target language, and the emitted peers are run as a cohort against the same conformance gate as the reference implementations. The cohort spans dozens of languages, and it deliberately includes substrates that share almost nothing: managed runtimes and manual memory, garbage-collected and reference-counted, a stack machine, an array language, a live image-based system, and ports to more than one instruction set. When a peer in such a language reaches the same bytes on the same vectors, the agreement is not attributable to shared idiom, shared libraries, or shared habits of mind — there are none to share.
What this demonstrates has to be stated carefully, because the obvious reading is stronger than the true one. The generated peers share a generation lineage. They are not independent implementations, and a cohort of them all passing one author’s vectors is cohort-consistent rather than independently convergent. What the cohort establishes is that the specification is precise enough to be mechanically realized across substrates with nothing in common — which is a claim about the specification, not about the number of people who have implemented it. The independent evidence remains the three bespoke implementations, and the two kinds of evidence should be reported separately rather than summed.
Two observations survive that caveat. First, no new wire contradictions surfaced after roughly the first eight peers, which suggests the core surface is tight rather than under-specified — had the specification been leaving decisions to the implementer, the additional languages would have kept finding them. Second, the exercise forced a distinction the specification needed anyway: a core conformance profile separable from the extension surface, so that “this peer conforms” names a definite set of obligations rather than an open-ended one.
The cohort’s per-peer state — which peer, which specification version, which oracle commit, and what is known to be missing — is published as a matrix rather than a headline. It is re-measured against newer oracles rather than carried forward, and the figures move when it is; a result quoted without its oracle commit and its pass/warn/fail/skip breakdown is not a conformance claim. The current tallies live in that matrix, and they belong there rather than here: a figure printed in a paper is a measurement stripped of the scope that made it meaningful, and it dates the moment the cohort grows. What travels is the discipline, not the number.
Why this is faster, not slower. The naive intuition is that three implementations mean three times the work. The actual outcome is the opposite: the largest cost in distributed-protocol design is specification ambiguity that survives until production. Catching an ambiguity at the implementation stage — when only the three peer codebases exist and no deployed users do — costs one round of spec-and-implementation work. Catching the same ambiguity in production costs a coordinated migration across all deployed peers, an incompatible-version dance, and breaking existing users. The three-peer model collapses this cost. Ambiguities are forced out before deployment because the implementations literally cannot agree until the spec is unambiguous.
What the methodology requires of the spec. Language-neutral normative text; concrete wire formats and hash algorithms spec-fixed (SHA-256 as the baseline hash, CBOR with deterministic encoding); pseudocode for algorithms where implementations could legitimately disagree if left to taste (capability verification, emit ordering, handler dispatch). The disciplines are not optional — they are what makes three-implementation validation actually validate.
Honest gaps in the loop. The clean description above is the loop at its best. Several real limitations sit alongside it.
- Three may not be enough. Three surfaces ambiguities better than one or two, but it is a small number. Agreement among three is evidence that the spec is unambiguous to people who think like the three implementers — a fourth implementation from outside the team’s reasoning style might still find a divergence. Premature convergence at is a real risk.
- The implementations are not fully isolated. All three are driven by one overarching team. Implementers talk to each other, share design discussions, and absorb each other’s assumptions. Clean independent implementation is an ideal that is hard to achieve in practice; some of the agreement is the team agreeing with itself.
- Spec review sometimes lags implementation. To keep moving, implementations occasionally align on a reading pragmatically before spec review. We try to bring such alignments back to spec/architecture review when possible, but the loop is not as clean as its description.
- The spec is narrative. The text uses prose plus pseudocode plus normative clauses; this has worked for the iteration tempo but leaves more interpretation room than formal specification would. Formal methods (TLA+, Lean) sit in Limitations as the natural complement that has not been done.
- Encoded biases and bugs. Three implementations cannot catch a bug that lives in the spec itself; the loop validates cross-implementation agreement, not spec soundness. The team’s blind spots and the project’s tooling biases are likely encoded somewhere.
What it does not claim. Three implementations do not prove correctness. They prove the spec is unambiguous to within the team’s reasoning style, not that it specifies the right thing. The methodology surfaces inconsistencies, not unsoundness; the spec’s own bugs and biases pass through unfiltered. The result has converged technically; that is real, but it is not the same as a soundness claim.
Technical convergence is not social convergence. The loop gets the protocol to a state where implementations agree and the wire format is stable — technical convergence. It does not, by itself, get other people to independently arrive at the same primitives or to adopt them. Social convergence has its own dynamics: substrate attractors that hold designs in adjacent shapes, the invisibility of emergent properties before someone has built with them, the friction of moving a working ecosystem onto a new substrate. A clean technical substrate makes social convergence more likely; it does not produce it. The broader corpus (especially Convergent Evolution) takes up this question explicitly. Anyone reading the spec presented here should be aware that converging the protocol and converging the field are different problems.
13.4. Normative Algorithms
Five normative algorithms are specified and must match across implementations:
- Content hash: SHA-256 of ECF-encoded
{type, data} - Signature: Ed25519 sign/verify
- Peer ID:
Base58(key_type || hash_type || SHA256(public_key)) - ECF encoding: deterministic CBOR subset
- URI normalization
SHA-256 and Ed25519 are the conformance baseline, not a hard-wiring: a one-byte format code selects the hash (SHA-384, 0x01, is validated and cross-implementation byte-equal) and key_type selects the signature scheme (Ed448, 0x02). The byte-exact agreement requirement holds per selected algorithm.
Plus conformance algorithms (type resolution, type validation).
13.5. Cross-Implementation Validation
Same entity same hash in Go, Python, Rust (cross-validated). Same delegation chain same accept/reject across implementations. This validates the normative algorithms are unambiguous.
13.6. Conformance Requirements
The spec defines three levels: MUST (wire framing, hashing, capability verification, dispatch, connection protocol, entity fidelity), SHOULD (root grant tracking, type system L1, tree extensions, operational state), MAY (type validation L2, system extensions, additional hash/key algorithms).
The MUST floor also covers the substrate staying up, not only being correct. A conformant peer’s content store and tree index must be safe under concurrent dispatch; under sustained load it must stay responsive, bound its resources, never silently drop a request it admitted, not crash, and recover when load drops; and it must enforce finite limits on inbound payload size and capability-chain depth, rejecting over-limit input with a coded error while continuing to serve. These are outcome guarantees — graceful degradation, no silent loss — not throughput or latency promises, which are implementation- and deployment-dependent. The limit values are configurable defaults, not protocol constants.
14. Discussion
14.1. Construction and Reduction
Most protocols accumulate: features are added as they are needed, and the protocol grows. This protocol alternated instead — each pass built mechanisms for the next concern, then tested whether the substrate already present could absorb them. The result is six primitives, each independently necessary, together sufficient. The structure surfaced through the cycle rather than being designed up front.
14.2. Irreducibility
The six primitives have been tested by the cycle itself. Every reductive pass that did not remove one is evidence the primitive resisted removal under active pressure to remove it. The standing question: is there a reduction the cycle missed? Removing any one of entity, identity, tree, emit, execution, or peer should either lose a property the system currently has or expose a redundancy the cycle did not catch. No such reduction has been found so far.
14.3. Scope
This paper is the protocol layer. Two analyses build on it and are not attempted here: the computational reading of EXECUTE as a reduction (see The Entity Church Architecture), and the operating-system framing of a fully-loaded peer (see DEOS). The protocol itself is not a framework or library — it has specific structure, and it does not prescribe domain semantics. Handlers are free.
14.4. Limitations
No formal verification: protocol model checking (TLA+) is invited, not attempted. Correctness is validated by implementation, not proof. No production-scale evaluation: three implementations exist but no large deployment. Performance characteristics are uncharacterized at scale. Streaming data: content addressing requires content to be fixed for hashing. Continuous streams require discretization at the boundary — a genuine tension, not a defect.
Generated under prompt-and-review. This paper, like the rest of the corpus, the supporting implementations, and the architectural specifications, is LLM-generated under direction from the author. The author provides prompts, evaluates outputs, redirects, and approves — text, code, and design refinements are generated rather than directly authored. The development methodology described in §The Development Loop above is what the prompt-and-review tempo makes tractable; the honest gaps catalogued there (three may not be enough, peers not fully isolated, encoded biases) apply to the generation of this paper too. A real factor readers should weigh.
15. Conclusion
The entity core protocol is defined by six primitives: entity, identity, tree, emit, execution, and peer. These six are irreducible — the reducibility analysis found no further simplification. Remove any one and the system loses expressiveness.
The protocol shrank while the type system grew. What remains is minimal: the substrate the construct-and-reduce cycle could not absorb into the entity model.
On its own, the core protocol provides typed content-addressed storage, a mutable namespace with handler dispatch, per-message capability security, self-describing types, and emergent versioning. The extension architecture composes on top without modifying the core — the substrate-bridge extension set covering reactive computation, version coordination with peer sync, subscriptions, durable workflow, queries, content distribution, history, messaging, and time — all compose through the same six primitives.
Three open invitations to refute the closure claims sit alongside the protocol. If any of the six primitives can be removed without losing a property the system currently has, the irreducibility analysis is wrong. If any interaction requires a structurally distinct third message type, the two-message reduction is incomplete. If any representable structure escapes the bootstrap types, the self-description claim is wrong. None has been identified.
Future work: formal protocol verification (TLA+), performance at scale, production deployment, domain bridge catalog.