The Entity System
A Computational Information Substrate
The Entity Core Protocol is the working specification this paper sits underneath: content-addressed typed data, a mutable named tree over an immutable content store, two message types that dispatch by path, capability-based authorisation, peer-to-peer communication. The six primitives we examine here — Entity, Identity, Tree, Emit, Execution, and Peer — are what surfaced when we asked what minimal set of irreducible concerns the protocol cannot be expressed without. The primitives divide into three domains: informational (Entity, Identity, Tree), temporal (Emit, Execution), and spatial (Peer). Self-description and fixed-point types emerge at three primitives. Mutability — and with it the structural potential for versioning, audit, and convergence detection — emerges at four. Computation, which actualizes these latent properties, emerges at five. Distribution at six. At each step, properties appear that could not exist at the previous step. We test irreducibility by removing each primitive in turn and documenting what is lost. Existing systems — Git, IPFS, gRPC, Plan 9, AT Protocol, Nostr, Holochain, Urbit — map to subsets of two to four primitives, with gaps corresponding to properties they lack. No known system implements five or more. A system-extensions layer covering messaging, reactive computation, version coordination, subscriptions, content distribution, history, and networking compose through the same six primitives without modifying the core protocol. Three independent implementations (Go, Python, Rust) validate cross-platform conformance, and a generated peer cohort spanning dozens of languages — sharing a generation lineage, so evidence about the specification’s precision rather than about independent convergence — finds no language wall. Open questions remain: whether a primitive can be removed without losing the system, whether a seventh substrate primitive is independently necessary (separate from the surface primitives of type description and authorization analyzed in Dimensional Completeness, or the surface primitives of application architecture analyzed in Application Architecture), and whether a formal proof of irreducibility can be constructed.
1. Introduction
This paper examines six primitives for distributed information systems — Entity, Identity, Tree, Emit, Execution, Peer — and asks whether they are irreducible. The primitives surfaced from working on The Entity Core Protocol; the next section sketches the protocol briefly, and the rest of the paper turns to the primitives themselves.
The approach is combinatorial. We examine what properties emerge at each composition level — from single primitives through the full six. Self-description and fixed-point types emerge at three primitives. Mutability — and the structural potential for versioning, audit, and convergence — emerges at four. Computation, which actualizes these latent properties, emerges at five. Distribution at six. At each step, properties appear that could not exist at the previous step.
We test irreducibility by removing each primitive in turn and showing what is lost. We do not claim this is the only possible decomposition, but we have not found a way to simplify it further.
Existing systems — Git, IPFS, gRPC, Plan 9, AT Protocol, Nostr, Holochain, Urbit — map to subsets of two to four primitives. The gaps in each correspond to the primitives they lack. We have not found a system that implements five or more of the six.
Three independent implementations (Go, Python, Rust) validate cross-platform conformance, and peers generated from the specification into dozens of further languages reach the same bytes. A system-extension set — messaging, reactive computation, version coordination with peer sync, subscriptions, content distribution, history, time, and query — composes through the same six primitives without modifying the core protocol.
The Entity Core Protocol specifies the protocol itself. The Entity Church Architecture develops the computational model that arises from these primitives.
2. The Entity Core Protocol
The Entity Core Protocol is a working specification for distributed information systems. Its surface is small:
- Content-addressed typed data as the basic unit. Every value is
{type, data}; the unit’s identity is the hash of its canonical encoding. - A mutable named tree over an immutable content store. The content store maps
hash $\to$ entity; the tree mapspath $\to$ hash. Paths are mutable; content is not. - Universal addressing. Every entity has a name, a location, and an address:
peer/pathresolves to a content hash in some peer’s tree. The namespace is peer-isolated by construction, so trees from different peers compose without conflict; identical content shared across peers deduplicates automatically. Whether a given entity is reachable from where you sit is a separate question — capability-gated, network-dependent — but addressability itself is unconditional. - Two message types.
EXECUTEcarries a typed operation against a path;EXECUTE_RESPONSEreturns the result. There is no separate query, subscribe, or update message — they are allEXECUTEagainst handlers registered in the tree. - Four-dimensional capability grants (handlers, operations, resources, peers) with cryptographic attenuation. Capabilities are themselves entities, content-addressed and verifiable independently of session.
- Peer-to-peer communication. Each peer has content-derived identity, hosts its own tree, and exchanges entities with other peers under capability constraints.
Three independent implementations (Go, Python, Rust) speak the protocol on the wire. The Entity Core Protocol specifies the protocol in full; the sketch above is only enough to motivate what follows.
2.1. What surfaced
Working on the protocol returned six concerns that everything else rests on:
- Entity — the typed data unit
- Identity — content-derived hash
- Tree — mutable namespace over immutable content
- Emit — atomic state change
- Execution — typed dispatch
- Peer — the participant
The rest of this paper examines these six directly: what each one is, what they depend on, what properties emerge as they compose, and where existing distributed systems sit relative to them.
2.2. The substrate, the protocol, and the implementations
The entity system in this paper’s title refers to the abstract information substrate the six primitives produce when they compose — not to any specific implementation. The Entity Core Protocol is one instantiation of the substrate: a specific wire format, dispatch model, and capability scheme that realizes the six primitives concretely. The Go, Python, and Rust codebases are three implementations of that protocol. Substrate, protocol, and implementations are different things at different levels. When this paper says “the system,” it means the substrate; the protocol is the concrete reference we point at when specificity helps.
3. The Six Primitives
Each primitive is defined by what it is, what it provides, and what depends on it. The six divide into three domains:
- Informational (E, I, T): structure, identity, naming — no time, no space, no agency
- Temporal (M, X): change and directed action enter
- Spatial (P): position and perspective enter
This division is not merely a classification. It reflects a dependency structure: the temporal primitives depend on the informational ones, and the spatial primitive depends on both.
3.1. Entity
The fundamental data unit: {type: string, data: any}. Type is constitutive — an entity without a type is not an entity. This distinguishes the entity 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. Identity
Same {type, data} produces the same hash, everywhere, always. Different type produces a different hash even with identical data. Identity is intrinsic — derived from what something is, not assigned by an authority.
ECF (Entity Canonical Form) is a deterministic CBOR encoding that ensures identical bytes for identical data. This makes the hash function a true content-derived identity: two independent implementations that encode the same entity will produce the same hash.
3.3. Tree
Path hash: named organization over immutable content. The tree is “what things are called” — a mapping from paths to content hashes. The content store (hash entity) is “what things are.”
A given tree state is itself a set of bindings — a snapshot. The tree as a structural concept is informational. What makes it appear mutable is Emit (M) — the act of replacing one set of bindings with another. Mutability belongs to M, not to T.
The tree is a logical namespace (a flat path hash mapping), not a filesystem. All paths are scoped to a peer identity.
The tree also functions as a relation space. Path segments can contain content hashes — signatures/{content_hash}, diff/{A}/{B}, merge/{A}/{B}/{base} — where the number of hash segments determines the arity of the relation. This allows the tree to express arbitrary n-ary relations over content, including content that does not yet exist (the hash space is larger than any concrete content store).
3.4. Emit
The atomic state crossing. Two 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. Emit is the temporal coupling of Identity and Tree — the point where both primitives extend into time.
Every state change is a sequence of emit crossings. This is where content (which persists by hash) meets naming (which changes over time). Emit introduces events, change, before-and-after.
3.5. Execution
Execution represents the evaluator — the mechanism that reads typed structures from the tree and produces new structures. At the protocol level, this takes the form of two message types: EXECUTE and EXECUTE_RESPONSE.
EXECUTE: dispatch typed parameters to a handler at a URIEXECUTE_RESPONSE: return a typed result
Execution introduces agency — directed transformation, not merely the change M already provides. An agent reads the tree, transforms entities, and emits new state. The evaluator is what makes information active.
The evaluator has two activation modes. In directed mode, an EXECUTE message invokes a handler explicitly — an agent requests a specific transformation. In reactive mode, an emit event triggers re-evaluation — the evaluator responds automatically to state changes (as in the compute extension’s reactive cascades). Both modes are aspects of the same primitive: the mechanism that reads typed structures and produces results.
Every interaction is an EXECUTE: queries, mutations, subscriptions, connection setup. The operation vocabulary is unbounded — any handler defines any operation. The message structure is fixed. Handlers are entities registered at tree paths. Dispatch is a tree walk: the longest matching prefix determines the handler. The tree is the dispatch table.
3.6. Peer
Ed25519 key pairs. Peer identity is itself content-addressed.
Capabilities are four-dimensional grants covering handler scope, resource scope, operation scope, and peer scope, with cryptographic attenuation chains. Each EXECUTE carries its own capability token — per-message authorization rather than session-based access.
Connection is a handshake of EXECUTE messages — a hello, then authenticate, whose response carries the initial capability grant. It uses the same dispatch mechanism as everything else — there is no separate connection protocol.
3.7. Dependency Structure
The informational primitives have a strict partial order:
- Entity Identity: the hash function takes
{type, data}as input - Identity Tree: the tree binds paths to content hashes
The temporal primitives depend on the informational:
- Tree Emit: the bind step of emit updates a tree binding
- Tree Execution: dispatch is a tree walk
The spatial primitive depends on both:
- Identity Peer: peer ID is a hash of the public key
- Execution Peer: connection establishment uses
EXECUTE
This dependency structure is not imposed — it follows from what each primitive needs as input.
4. The Pair-Relationship Structure
Primitives do not only exist as independent constructs. They interact pairwise whenever both are present. Each pair of primitives forms a pair-relationship — a structural coupling with observable content. Six primitives produce pair-relationships. The distribution of structural load across these 15 pairs is uneven and informative: most of the system’s engineering sits at pair boundaries, not inside individual primitives.
4.1. The 15 Pair-Relationships
Grouping by the 3+2+1 domain split:
| Class | Pairs | Character |
|---|---|---|
| Informational × Informational | EI, IT, ET | Constitutive substrate |
| Informational × Temporal | EM, IM, TM, EX, IX, TX | Where change enters |
| Temporal × Temporal | MX | Cascade, causality, reactivity |
| Informational × Spatial | EP, IP, TP | Position enters information |
| Temporal × Spatial | MP, XP | Distribution enters action |
By structural load:
- Heavy (11 of 15): EI, IT, ET, IM, TM, EX, IX, TX, MX, TP, XP. These carry the bulk of engineering surface — extensions, SYSTEM-COMPOSITION, capability and dispatch systems concentrate here.
- Medium (1): IP.
- Light (2): EM, MP.
- Negligible (1): EP — entities do not carry peer identity, by design.
The emit primitive M, from the previous section, is best understood in pair terms: M is the temporal coupling of I and T. The Store event is the IM pair in action (content enters the I-indexed store); the Bind event is the TM pair (tree binding updates). Together with IT as the static substrate, they form the emit triangle — one of several structural triangles that recur across the system.
4.2. The Dependency-Coherent Sub-Lattice
The dependency constraints above partition the binary subsets: exactly 9 subsets satisfy all dependencies strictly. These 9 form a sub-lattice:
EITMXP
/ \
EITMX EITXP
/ \ /
EITM EITX
|
EIT
|
EI
|
E
|
∅
The dependency-coherent sub-lattice is the skeleton of internally-coherent system configurations. Other subsets — those containing M without T, or P without I, for example — are structurally incomplete: they violate at least one dependency and cannot form a working system without external compensation.
Three monotone paths run through this sub-lattice from to E+I+T+M+X+P:
- Path A: $$ E EI EIT EITM EITMX EITMXP. Narrative: information time computation space.
- Path B: via EITX before EITM. Narrative: computation before time.
- Path C: via EITXP before EITMXP. Narrative: space before time.
The build-up sequence in the next section follows Path A because it tells the cleanest story. The other paths are also valid; the narrative choice is editorial, the lattice is structural.
4.3. Five Structural Triangles
Three-primitive subsets that recur across the system as recognizable units:
- EIT — self-description triangle. The type fixed point:
system/typeof typesystem/typelives here. - ITM — emit triangle. IT is the static substrate; IM extends I into time; TM extends T into time. The two-axis structure of emit is the triangle’s structural content.
- TMX — reactive dispatch triangle. The cascade loop (M triggers X; X emits M) closes here. The compute extension’s substrate.
- IXP — cryptographic capability triangle. Capability tokens are content-addressed entities (IX) transferred between peers (XP) verified by identity (IP).
- TXP — distributed dispatch triangle. Tree-walk routing across peer-namespaced paths. The structural shape of REST and HTTP.
These triangles are where engineering concentrates. Extensions actualize specific pair-bundles over them; system composition coordinates multiple actualizers where triangles are over-subscribed.
5. The Build-Up Sequence
Properties emerge as primitives compose. Each step adds properties that could not exist at the previous step. The build-up traces a progression through domains: the first three steps are purely informational, the fourth introduces time, the fifth introduces agency, and the sixth introduces space.
5.1. Step 1: Entity (E)
Typed data. A unit that carries its type. Nothing else — no identity, no address, no persistence.
Pair-relationships: none yet (pairs require two primitives).
5.2. Step 2: Entity + Identity (E+I)
Typed data with intrinsic identity. Content-derived hashing gives:
- Immutability: changing content changes identity (it becomes a new entity)
- Deduplication: same content is stored once
- Verification: anyone can check content against its hash
Known analog: typed IPFS blocks — content-addressed but without named organization.
Pair-relationships: EI activates. Heavy pairs: 1/11.
5.3. Step 3: Entity + Identity + Tree (E+I+T)
Typed, content-addressed, named data. The tree organizes entities into a namespace. This is where self-description emerges.
Types are entities (E). Types have content-derived identity (I). Types are stored at system/type/* in the tree (T). system/type is itself of type system/type. This is a fixed point — the type system describes itself in its own terms.
The recursion bottoms out at bootstrap types — a small set of primitives and meta-types that seed the type system. Self-description requires all three of E, I, and T: the entity carries its type, the type entity has verifiable identity, and the type entity lives at a known path where it can be discovered and where it describes itself.
E+I+T is the complete informational structure. It could, in principle, contain every structure, every relationship, every truth. You could navigate it, verify references, follow links between entities. It contains structural truth (the shapes of things) and referential truth (how things relate). Self-description is a structural fact — it holds without any computation.
But nothing happens. No state changes, no dispatch, no computation. It is pure information.
Known analog: a typed Git, if Git carried structural types rather than treating data as blobs.
Pair-relationships: IT and ET activate (both heavy). Heavy pairs: 3/11. The EIT self-description triangle is complete.
5.4. Step 4: Entity + Identity + Tree + Emit (E+I+T+M)
Adding emit introduces time. The tree can change — a path can be rebound to a new hash. The old entity still exists in the content store (content addressing preserves it), but the binding has changed. Before and after now exist.
This creates structural potential for several properties:
- Versioning: rebinding a path does not destroy the previous entity. It persists by hash. Every emit is structurally a version.
- Audit trail: the content store is append-only. Emit events form a sequence. Hash chains connect versions.
- MVCC: content addressing functions as a version column. Concurrent readers see consistent snapshots. Concurrent writers produce distinct versions (different hashes).
- Convergence detection: peers with the same hash at the same path have provably the same content, without needing a coordination protocol.
We say potential because these properties are latent in the structure. Without an evaluator, nothing tracks versions, maintains audit logs, or processes events. The content store grows as entities accumulate, but no agent reads, compares, or reacts to the changes. E+I+T+M is a mutable content-addressed store where time exists but nothing acts on it.
The potential matters because it constrains what evaluators can do when they arrive. Even fixed evaluators — like Git’s hash, merge, and diff — operating on E+I+T+M get versioning and audit structurally. The properties are latent in the data model; the evaluator actualizes them. This is why we say information precedes computation: the ground exists before any agent computes on it.
Known analog: no widely-deployed system exists at exactly this composition. Systems that reach E+I+T+M typically also have at least fixed evaluators.
Pair-relationships: EM (light), IM and TM (both heavy) activate. Heavy pairs: 5/11. The ITM emit triangle is complete — IT static substrate plus IM and TM extending into time.
5.5. Step 5: Entity + Identity + Tree + Emit + Execution (E+I+T+M+X)
Adding the evaluator actualizes the temporal properties that were potential at E+I+T+M. The raw materials were present — old entities preserved by content addressing, emit events forming a sequence — but organizing them into useful properties requires something that reads, compares, and acts:
- Versioning: the evaluator tracks, compares, and retrieves previous versions — the old entities were always there by hash; now something reads them
- Audit trails: the evaluator processes the emit event stream into a verifiable history log
- Reactive cascades: emit events trigger the evaluator, which processes changes and may emit further results — subscriptions, derived values, reactive computation
- MVCC: concurrent evaluators see consistent snapshots through content-addressed versions
Even fixed evaluators suffice for many of these. Git’s evaluators — hash, merge, diff, pack — are fixed operations on content-addressed data, yet Git has versioning, audit, and merge. The compute extension demonstrates a more expressive fixed evaluator: one that reads typed expressions (lambda, apply, if, let, lookup, literal) from the tree and reduces them reactively when dependencies change. This is Turing-complete computation without open dispatch — the evaluator is fixed, but its expression language is general.1
Open dispatch adds extensibility and agency beyond fixed evaluation:
- Handlers: entities registered at tree paths with typed interfaces
- Dispatch: tree walk from URI to handler, longest prefix match
- Operations: unbounded operation vocabulary per handler
- Self-extension: the system can modify its own behavior through the same mechanism it uses for data — handler registration is itself an
EXECUTEoperation
The transition from fixed to open evaluation is from tool to platform — from a system that does specific things to one whose capabilities are open-ended.
This is a complete local entity system. It computes, self-describes, versions, and audits. But it operates on a single machine.
Known analog with fixed evaluators: Git. Known analogs with open dispatch (individually): actor systems (Erlang/OTP), plugin architectures, application servers. But none combine open dispatch with full E+I+T+M — typed, content-addressed, self-describing, versioned data as the substrate for computation. Existing open-dispatch systems operate on untyped messages (Erlang), external schemas (gRPC), or assigned identity (databases). We have not found a system that combines all five.
Pair-relationships: EX, IX, TX, and MX activate (all heavy). Heavy pairs: 9/11. Four new heavy pairs in one step — the largest single-step unlock. The TMX reactive dispatch triangle is complete.
5.6. Step 6: All Six (E+I+T+M+X+P)
Adding Peer introduces space — position, perspective, and boundaries.
- Multi-peer coordination: peers exchange entities via
EXECUTEacross connections - Per-message authorization: capability tokens carried with each request
- Trust boundaries: capabilities attenuate (narrow, never amplify)
- Convergence detection: same hash at same path means converged, without coordination overhead
- Cryptographic delegation: content-addressed capability chains
Capability tokens are themselves entities — subject to the same identity, type, and addressing mechanisms as all other data. Authorization is not a separate system layered on top; it uses the same primitives.
Connection is a handshake of EXECUTE messages — hello, then authenticate, whose response carries the initial capability grant. The grant communicates the peer’s namespace layout. It uses the same dispatch mechanism as everything else.
Known analog: we have not found a system that integrates all six.
Pair-relationships: EP (negligible), IP (medium), TP (heavy), MP (light), XP (heavy) activate. Heavy pairs: 11/11 — full coverage. The IXP capability triangle and TXP distributed dispatch triangle are complete.
5.7. Observations on the Sequence
The informational primitives (E, I, T) require no universe, no time, no agents. Self-description emerges here as a structural fact. The fixed point (system/type describes system/type) holds as a property of the structure, not as a result of computation.
Time enters at M. The evaluator enters at X. Space enters at P. The build-up traces a progression through domains of physicality: from pure information, through time and computation, to distributed space.
A notable observation: the temporal properties (versioning, audit, MVCC) do not require open dispatch or extensibility. Even fixed evaluators — like Git’s hash, merge, and diff — operating on E+I+T+M are sufficient to actualize them. What open dispatch adds is extensibility and agency: the ability to register new handlers, define new operations, and extend the system’s behavior. The transition from fixed to open evaluation is from tool to platform, but even tools actualize the structural potential.
This observation — that information precedes computation in the build-up — is explored further in the Discussion.
Heavy-pair coverage per step. Tracking how many of the 11 heavy pair-relationships are active at each step:
| Step | Configuration | Heavy pairs activated | Cumulative |
|---|---|---|---|
| 1 | E | — | 0/11 |
| 2 | E+I | +EI | 1/11 |
| 3 | E+I+T | +IT, +ET | 3/11 |
| 4 | E+I+T+M | +IM, +TM (EM light) | 5/11 |
| 5 | E+I+T+M+X | +EX, +IX, +TX, +MX | 9/11 |
| 6 | E+I+T+M+X+P | +TP, +XP (others medium/light) | 11/11 |
Step 5 is the largest unlock — adding X activates four heavy pairs simultaneously, which is why computation, dispatch, convergence, and reactivity all emerge together at five primitives. Step 6 adds two heavy pairs (TP, XP), confirming that the spatial cluster contributes less structural load than the informational or temporal clusters — one reason removing P leaves a complete local system.
6. The Type System and Self-Description
Self-description emerges at E+I+T and is foundational to everything that follows. It warrants separate treatment.
6.1. Types as Entities
Every type is an entity of type system/type. Types are stored at system/type/{type_name} in the entity tree. Types have content-derived identity (their hash). Types describe entities. Types are entities. Therefore types describe themselves.
This circularity is not vicious — it bottoms out at a small set of bootstrap types that seed the type system itself.
6.2. The Fixed Point
system/type is itself of type system/type. The type that defines all types is defined by itself. This is a fixed point of the type-description function.
The recursion bottoms out at a small set of bootstrap types: primitive value types (string, bytes, integers, bool, null, any), the two meta-types needed for self-description (system/type and system/type/field-spec), and a few structural types for content hashes, paths, and type names. These bootstrap the type system. The protocol’s own structures — execute, execute_response, handler, capability token, grant entry, envelope, and others — are then defined as ordinary type entities using this bootstrap set. The type system describes the protocol; the bootstrap types describe the type system.
6.3. Structural Typing
Types describe shape: fields, field types, optionality. Validation is structural — does this entity match its type definition? — rather than nominal. The type system supports single inheritance, generics, and open types that preserve unknown fields for forward compatibility.
6.4. Types Cross the Wire
Entity types travel with the data. Unlike Protobuf (where schemas are compiled from .proto files, separate from the wire data) or Plan 9 (where data is untyped bytes), the entity protocol is typed end-to-end. There is no type gap at protocol boundaries.
6.5. Why E+I+T
Self-description needs all three informational primitives:
- E: types are entities — they carry a type field
- I: type entities have verifiable identity — their content hash
- T: type entities live at known paths (
system/type/*) where they can be discovered and referenced
Remove E and types are not entities — they cannot self-describe. Remove I and type entities have no verifiable identity — you cannot confirm that two peers have the same type definition. Remove T and types exist but have no address — they cannot be discovered or referenced by path.
7. Irreducibility: The Remove-One Test
For each primitive, we remove it and document what the system loses.
7.1. Without Entity (I+T+M+X+P)
An untyped content-addressed system. Data is blobs. No structural validation, no self-description, no typed interfaces. Handlers receive untyped bytes. The system cannot describe itself — there are no type entities because there is no type field.
Known analog: Git with dispatch. Lost: self-description, type safety, structural validation.
Heavy pairs lost: 3 (EI, ET, EX).
7.2. Without Identity (E+T+M+X+P)
A typed namespace system with assigned identity. Identity is a UUID or sequence number, not derived from content. This loses:
- Deduplication (same content, different IDs)
- Verification (cannot check content against ID)
- Convergence detection (same content does not produce same ID)
- Immutability guarantees (IDs persist, but content behind them could change)
- Cryptographic audit (no hash chains)
Known analog: a typed Plan 9 with mutable records. Lost: content integrity, convergence, deduplication, audit.
Heavy pairs lost: 4 (EI, IT, IM, IX) plus 1 medium (IP).
7.3. Without Tree (E+I+M+X+P)
Typed content-addressed dispatch with no persistent namespace. Where do handlers register? Where does state live? Content-addressed entities exist and can be dispatched, but there is no system/handler/* path to organize them, no system/type/* to store type definitions. The bind step of emit requires a tree — without it, emit reduces to “store + ??? + event.”
Known analog: stateless typed RPC with content-addressed parameters. Lost: namespace, organization, handler registration, persistent state.
Heavy pairs lost: 5 (IT, ET, TM, TX, TP) — maximum among removals.
7.4. Without Emit (E+I+T+X+P)
Typed content-addressed namespace with dispatch, but no atomic state crossing. What is lost is the structural guarantee that Store and Bind happen atomically, each producing independently observable events. Without this:
- No versioning by construction (state changes are not atomically tracked)
- No event stream (no events to react to)
- No reactive cascades (extensions that respond to state changes have no integration point)
This is the softest removal among the first five. With execution still present, a handler could implement Store-then-Bind-then-notify as a sequence of operations — reconstructing much of what emit provides, but as a convention rather than a structural guarantee. The loss is not that state cannot change, but that the system no longer guarantees the atomic two-axis crossing with observable events on each axis. Versioning and audit become implementation responsibilities rather than structural properties.
Known analog: typed content-addressed RPC with a namespace but no state guarantees. Lost: atomic state crossing, structural versioning, event integration.
Heavy pairs lost: 3 (IM, TM, MX) plus 1 light (MP).
7.5. Without Execution (E+I+T+M+P)
Typed content-addressed namespace with state changes and peers, but no evaluator. A distributed database where data accumulates but nothing acts on it — no handlers, no reactive cascades, no directed operations. The tree can change (emit still works), but no agent reads the changes, processes them, or produces derived results. Versioning, audit trails, and MVCC remain structural potential that nothing actualizes.
Known analog: a distributed content-addressed typed object store. Lost: computation, reactive evaluation, handlers, operations — the evaluator and everything it provides.
Heavy pairs lost: 5 (EX, IX, TX, MX, XP) — tied with T for maximum among removals.
7.6. Without Peer (E+I+T+M+X)
The full system on a single machine. No distribution, no capabilities, no connection, no multi-agent coordination. Still useful — a complete local entity system with computation, self-description, versioning, and audit. But no trust boundaries, no convergence across machines, no delegation.
Known analog: a local entity system (this exists as single-peer mode in the implementations). Lost: distribution, capabilities, trust, multi-agent coordination.
Heavy pairs lost: 2 (TP, XP) plus 1 medium (IP) — minimum among removals, which is why P’s removal leaves a complete local system.
7.7. Summary
Removing any of the first five primitives (E, I, T, M, X) produces a qualitatively different and lesser system. Removing Peer produces a complete local system — useful, but not distributed. This suggests a natural separation: E+I+T+M+X form the computational core; P extends it to distribution.
The remove-one test also reveals that M and X are deeply interdependent. Without M, the evaluator (X) can still dispatch and compute, and could reconstruct state-crossing behavior through handler operations — but loses the structural guarantee of atomicity. Without X, emit (M) can still change state, but nothing reads, processes, or acts on the changes. Each can partially compensate for the other’s absence, but each contributes something the other cannot fully reconstruct: M contributes the atomic state crossing as a structural guarantee; X contributes the evaluator that actualizes what the state crossings make possible. They are, in a sense, two facets of temporality — M is the mechanism of change, X is the mechanism that gives change computational structure.
P is always physically present. Every running system operates on a device, in a process, with a position and perspective. A system with no peer modeling does not lack a peer — it lacks peer awareness. The device is a peer in the physical sense; the partial levels (described below) measure how much the system recognizes this fact.
8. Partial Primitives
Systems do not simply “have” or “lack” a primitive. Each primitive has internal structure that can be implemented to varying degrees. The gradients below are not formal decompositions — other segmentations are possible, and companion papers develop more detailed analyses (see Dimensional Completeness; Convergent Evolution). We present them here as an exploratory tool: a shorthand vocabulary for describing where systems sit along each primitive’s spectrum, which we use throughout this paper and the extended series.
Entity (E): E0 (raw bytes) E1 (hardcoded type tags) E2 (integer/string kinds) E3 (external schemas) Full E (types as first-class entities)
Identity (I): I0 (no identity) I1 (assigned identity) Full I (content-derived hash)
Tree (T): T0 (flat keys) T1 (single-level paths) T2 (hierarchical paths) Full T (path hash with two address spaces)
Emit (M): M0 (no state crossing) M1 (non-atomic writes) M2 (atomic, no events) Full M (atomic Store + Bind with independently observable events on each axis)
Execution (X): X0 (fixed evaluators) X1 (fixed verbs, fixed paths) X2 (fixed verbs, open paths) X3 (open dispatch, no registration) Full X (typed open dispatch with handler registration)
Peer (P): P0 (no peer awareness) P1 (client/server) P2 (authenticated endpoints) P3 (symmetric peers) P4 (role-based access) Full P (entity-native capabilities)
The most consequential transitions appear to be:
- X0 X2: tool to platform. HTTP crossed this threshold; Git did not.
- E2 Full E: types as first-class data. We have not found a widely-deployed system that has crossed this independently.
- I1 Full I: assigned to content-derived identity. This reverses the identity model — identity becomes intrinsic rather than assigned.
- P3 Full P: symmetric peers to capability-bearing peers. This appears to require E+I+T as substrate for the capability tokens.
Partial levels predict properties. A system with E1 can store typed data but cannot self-describe. A system with X2 can dispatch to any path but cannot discover handlers. A system with P3 has symmetric peers but no trust management. Full dimensional analysis of primitive substructure is developed in Dimensional Completeness; full landscape application with partial scoring in Convergent Evolution.
9. Where Known Systems Stop
Existing systems implement subsets of the six primitives. The gaps correspond to properties they lack. We organize the landscape by primitive count.
The systems named in this section are anchor cases — those we found most informative for the structural argument, each chosen because it stabilizes at a recognizable point in the primitive space. Each mapping is an analyst-interpreted scoring of the system at a particular point in time; primitive levels and partial forms are documented judgments rather than automated measurements of running code. A broader survey — the named anchors plus additional infrastructure, databases, federated protocols, and editor tooling — informs the patterns described here: the landscape figure below plots thirty-four entity-arrangement systems, drawn from a full cross-corpus analysis of roughly fifty manifestations developed in Convergent Evolution. We keep the treatment here narrative and refer to the named anchors only where they sharpen a structural claim.
9.1. Two-Primitive Systems
Git (I+T, with E1, X0, P3): Content-addressed tree. Hardcoded types (blob, tree, commit, tag), fixed evaluators (hash, merge, pack, diff), symmetric remotes. Git became a platform for content-addressed state management (GitOps, CI/CD, infrastructure-as-code) — evidence that even two full primitives with partial forms of the others create significant value.
IPFS (I+T, with E1, P3): Content-addressed distribution. Codec-tagged blocks (E1 — type tags, but not structural types), peer-to-peer distribution. Compared to Git, IPFS trades fixed evaluators for broader content distribution. Neither has structural types or dispatch.
gRPC (E+X, with E3, P1): Typed dispatch with external schemas via .proto files and client/server topology. No content addressing, no namespace. A typed RPC platform.
Plan 9 (T+X, with X2, P1–P2): Namespace with dispatch — “everything is a file.” Read/write/walk over an open namespace. Untyped bytes, no content addressing.
9.2. Three-Primitive Systems
Nix store (I+T+X, with E1–E2, X0): Content-addressed namespace with fixed evaluators. Domain-specific derivation types, build/hash/store operations. Domain-locked to builds, like Git is domain-locked to version control.
Datomic (E+T+M, with I1, P1): Typed namespace with state events. Assigned entity IDs (not content-derived), client/server. Rich query and temporal model, but no content addressing.
9.3. High-Primitive Systems
These are the systems closest to the entity system, each reaching three to four primitives. Each is instructive because each stops at a different point and for different reasons.
AT Protocol (E+I+T+P, with P4): Content-addressed typed data across peers. Per-user Merkle Search Trees. Federation with moderation. But no dispatch — computation happens in application code, not in the protocol. No atomic emit. This is the closest structural match we have found. Notably, all of AT Protocol’s gaps appear to be additive rather than requiring destructive changes to existing architecture.
Nostr (E+I+X+P, with E2, X3, T0, P3): Content-addressed signed events with integer kinds. NIP-90 provides ad-hoc dispatch. Flat — no tree, no structural types, no handler registration. Nostr independently arrived at {type: kind, data: content} with content-addressing, a convergence worth noting.
Holochain (E+I+X+P, with P4): Closest overall by dimensional count. But DNA determinism locks application logic at deploy time, and types are defined in Rust rather than as protocol-level data. The security model (“trust the code” — all peers must run identical validation) is architecturally incompatible with capability-based authorization.
Urbit (T+X+P, with P4): Closest in vision — a personal computing environment built on a typed namespace. Independently discovered {type, data} (vases). But no content addressing — the seed crystal that triggers structural cascading in other systems is absent. The Nock/Hoon language layer creates a significant barrier to architectural evolution.
9.4. Summary Table
| System | Full Primitives | Partial Levels | Key Gap |
|---|---|---|---|
| Git | I+T | E1, X0, P3 | No types, no dispatch, no emit |
| IPFS | I+T | E1, P3 | No types, no dispatch, no emit |
| gRPC | E+X | E3, P1 | No content addressing, no namespace |
| Plan 9 | T+X | X2, P1–P2 | No types, no content addressing |
| Nix | I+T+X | E1–E2, X0 | No types, no emit, no distribution |
| Datomic | E+T+M | I1, P1 | Assigned identity, no dispatch |
| AT Protocol | E+I+T+P | P4 | No emit, no dispatch |
| Nostr | E+I+X+P | E2, X3, T0, P3 | No tree, integer kinds |
| Holochain | E+I+X+P | P4 | DNA determinism, types in Rust |
| Urbit | T+X+P | P4 | No content addressing |
9.5. Attractor Compositions
Most systems stabilize at two to three full primitives, with partial forms of one or two more. The four closest systems each reach three to four primitives. No system we have examined implements five or more.
Systems appear to stabilize at what we call attractor compositions — natural resting points where the current primitive set is sufficient for the domain:
- Content-addressed VCS: I+T+E1+X0 (Git — a platform for state management)
- Typed RPC: E3+X+P1 (gRPC — a platform for typed dispatch)
- REST-like dispatch: X2+T1+P1 (HTTP — a platform for open dispatch)
- File-as-interface: T+X2 (Plan 9 — a platform for namespace)
The modern technology stack integrates these partial-primitive platforms: Git manages state (I+T), HTTP handles dispatch (X2), Kafka handles events (partial M), PostgreSQL handles typed data (E+T+M). The integration layer — CI/CD pipelines, REST APIs, webhooks, service meshes — wires them together. This integration work is, in a sense, the cost of not having the primitives unified: each platform covers its slice, and the gaps between slices are filled by infrastructure.
The four attractor compositions named here are illustrative anchors — the platforms whose stabilization point is sharpest. The broader corpus survey surfaces additional structural regions (content-infrastructure tooling, consensus-KV substrates, peer-federation messaging, editor-and-knowledge tooling, relational-server DBMS, and a commercial-SaaS region, among others) where multiple systems cluster around shared primitive-level signatures. These regions are inductive centroids of the surveyed corpus rather than canonical categories; the full inventory is developed in Convergent Evolution and the underlying structural methodology, which generalizes the per-domain analysis applied here, is developed in A Structural Methodology for Information System Domains.
10. The Reduction
The system did not begin as architecture. It began as the distributed-substrate piece of an earlier entity-centric tool whose local entity model needed cross-peer coherence. The realization that this required a protocol, not just a refactor, was the leap into the architectural work; everything since has been alternating construction and reduction over the substrate that leap produced. The structural foundation revealed itself through that alternation.
10.1. Architectural Methodology
The methodology is a construct-and-reduce cycle guided by a small set of design values that hold at the system level:
- Simplicity — every primitive must justify its presence; a mechanism that another already covers does not stay.
- Convergence as the stopping rule — construction stops introducing new mechanisms and reduction stops removing them.
- Math where it reaches; considered convention where it does not — the spec follows the math where structure is mathematically determined (content addressing, deterministic encoding, hash-derived identity, the dispatch primitive) and records the convention elsewhere.
- The substrate settles so layers above it can — extensions, application architecture, and user-space rest on the converged substrate; if it kept shifting, they could not stabilise.
The cycle that assembled the protocol — its structurally significant named moves (the substrate leap, the relay insight, the wire reduction, the capability invariant), the representative reductions, and the cost-asymmetry argument that drove pre-release intensity — is developed in The Entity Core Protocol §The Reduction.
10.2. The Pattern
The reductive passes have a consistent shape: removals are structural (a mechanism is replaced by the entity model) and additions are types (the type system grows to cover what the mechanism previously did). The protocol shrank while the type system grew.
This is what we would expect from reduction toward a single substrate. If the entity model is expressive enough, mechanisms that were once separate can be expressed as typed data within the model. This pattern — structural removal, typed addition — is what other papers in this corpus refer to when they describe the system as having a small protocol surface and a large type-level evolution space (see The Entity Core Protocol; The Universal Computational Genome; Convergent Evolution).
11. The Extension Architecture
The extension architecture provides evidence that the six primitives compose well — that a broad range of distributed system concerns can be expressed through them without modification.
11.1. How Extensions Work
An extension registers a handler at a system/* path, defines its types, and optionally consumes emit events. It uses the same EXECUTE dispatch, the same capabilities, the same tree. There is no separate extension API.
This means extensions are not a separate mechanism. They are handler registrations that follow the same protocol as any other handler. The distinction between “core” and “extension” is a matter of which handlers are defined in the specification versus which are registered at runtime.
In pair-relationship terms, each extension is an actualizer: it pushes a specific pair-bundle — some subset of the 15 pair-relationships — from latent structural potential into fully expressive behavior. A subscription extension actualizes MX and XP (reactive cross-peer dispatch). A compute extension actualizes MX, IX, and TX (reactive dispatch with convergence). A history extension actualizes IM, TM, and TX (observing both emit events and dispatching queries over the log).
11.2. The System-Extension Layer
The system-extension layer above the core protocol is itself stratified. The architecture team’s working classification distinguishes a substrate-bridge tier (core extensions that bridge substrate primitives to application-architecture surface), an operational tier (extensions that any deployed multi-peer system needs but that do not contribute structural bridge edges), and exploratory and first-pass-grounding tiers (extensions held loosely or kept as reference designs).
The substrate-bridge extensions the architecture ships are:
| Extension | Domain | Primary pair-bundle |
|---|---|---|
system/tree (extended) |
Snapshots, diffs, merges, view-trees over the core tree | TX |
system/type |
Value-level constraints and type-analysis operations | ET, EI |
system/content |
Content store ingestion, chunking, manifests; consumption-format descriptors as tags over blobs (proposed) | EI, IT |
system/inbox |
Async cross-peer message delivery | XP, MX |
system/subscription |
Reactive event streams, filtered fanout | MX, TM, TP |
system/continuation |
Durable execution chaining, cross-peer workflow | MX, IX, EX |
system/compute |
Expressions, derived entities, reactive computation | TMX, EX, IX |
system/query |
Secondary indexes and compositional queries | TX, ET |
system/revision |
Versioning, three-way merge, peer-to-peer sync (DAG + delta) | ITM, TP, XP |
system/history |
Per-path transition recording, audit, rollback | IT, IM, TM |
system/clock |
System time — wall-clock plus logical/vector references | TM, MX |
Each is a structural actualizer in the sense developed above: each pushes a specific pair-bundle from latent potential into expressive behavior. The set is empirically what a peer needs to host the canonical application-architecture concerns; the broader analysis of how these extensions map to a twelve-primitive application-architecture surface is developed in Application Architecture.
Beyond these substrate-bridge extensions, the system distinguishes three further extension categories that any deployed system encounters but that play different structural roles:
- Operational extensions — identity management (peers, controllers, K-of-N quorums, certs, rotation), peer attestation, role-based authority, group membership, network connectivity, peer discovery, and (gap-flagged) relay routing. These provide the operational semantics needed to run a deployed multi-peer system. They do not contribute substrate-to-application bridge edges in the structural sense above; they sit alongside the substrate-bridge extensions as a separate concern.
- First-pass-grounding extensions — currently
system/transaction, a draft that frames multi-binding atomic writes with an observation boundary. Held loosely; anti-fragmentation work, not yet load-bearing for the substrate argument. - Exploratory extensions — currently
system/durability, marked optional and not actively developed, preserved as a reference design after a scope-overreach retraction.
11.3. Composability as Evidence
That the substrate-bridge extensions all compose through the same six primitives without modifying the core protocol suggests something about the primitive set.
The framework provides a sharper explanation: extensions compose because their pair-bundles are mostly orthogonal. When two extensions actualize disjoint pair-bundles, they do not interfere. When pair-bundles overlap, coordination becomes necessary — and this is what the SYSTEM-COMPOSITION layer specifies, particularly at the two over-subscribed triangles (ITM, where history, query, and revision all observe emit events; TMX, where compute, subscription, and clock all exercise reactive dispatch) and at the XP boundary (where inbox, continuation, network, and subscription all cross peer connections).
When extension design violates orthogonality, the spec process catches it. The clearest example is the retraction of the durability extension: an apparatus that pattern-matched on log-system conventions without a concrete deployment driver was lifted out of the normative spec and preserved as an exploratory reference. This orthogonality discipline — and the willingness to retract — is an active structural property of the system, not a passive design claim.
11.4. Four Document Layers
The extension architecture occupies a specific position in the spec architecture:
- Core protocol — the primitive substrate, the specification of the graph with its 11 heavy pair-relationships.
- SYSTEM-COMPOSITION — coordination rules for how multiple extensions interact over shared pair-surfaces (consumer ordering, cascade depth, convergence classes).
- Extensions — individual actualizers, each specified as its own document.
- Guides — composition patterns that combine multiple existing actualizers without adding new structure. (Each guide can be formalized into a reusable SDK function once the pattern is common.)
Features route to the appropriate layer: a new pair-bundle → extension; a coordination rule for shared surfaces → SYSTEM-COMPOSITION; a composition of existing actualizers → guide. This four-layer structure is where ergonomics lives — the primitives are universal but minimal; extensions provide common capabilities; guides and SDK helpers provide the practical developer experience.
We note composability as suggestive rather than conclusive. It is possible that the extensions simply have not yet reached the boundary of what the primitives can express. But across the substrate-bridge extension set spanning a broad range of distributed system concerns, the primitive set has been sufficient, and the orthogonality discipline that keeps extensions from cross-cutting has been empirically enforceable.
12. Implementation and Evaluation
12.1. Three Implementations
- 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 — at parity on the conformance surface; an independent stack reading the same spec, useful at surfacing ambiguities the other two would miss.
- Rust — at parity on the conformance surface; targets performance and portability.
The three implementations are not independent attempts at the same target — they are the operational loop through which the specification itself is refined: the spec is the language-agnostic invariant, the implementations are its validators, and divergence between them is feedback to the spec. The full development methodology — the loop’s stages, why three implementations rather than two, why this is faster rather than slower, what it requires of the spec, and what it does not claim — is developed in The Entity Core Protocol §The Development Loop.
12.2. No Privileged Language
If the substrate is what we claim — a structure that information takes, rather than a design someone chose — then no language should be privileged in expressing it. The six primitives say nothing about runtimes, memory models, or type disciplines, so a peer ought to be writable in any of them.
This is testable, and it has been tested more aggressively than three implementations can test it. A generator derives a complete core peer from the specification for a target language, and the resulting peers are run as a cohort against the same conformance gate. The cohort spans dozens of languages and deliberately includes substrates with nothing in common: garbage-collected and manually managed, compiled and interpreted, a stack machine, an array language, an image-based system. They reach the same bytes.
The caveat matters as much as the result, and it points the other way from the enthusiasm: generated peers share a generation lineage, so they are not independent implementations and must never be summed with the three bespoke ones into a single count. What the cohort shows is that the specification is precise enough to be realized mechanically across substrates that share no idiom — evidence about the specification’s precision, not about independent discovery. The independent evidence is the three implementations; the cohort evidence is the absence of a language wall. They are different claims and this paper keeps them apart. The Entity Core Protocol develops both.
The relevance here is what it says about the substrate rather than about the tooling. A system whose realization depends on a particular language has, somewhere in it, a commitment that is the language’s rather than the structure’s. Nothing in the primitives has yet turned out to be such a commitment — which is weak evidence for the discovery framing, and worth stating as weak.
12.3. Normative Algorithms
Five normative algorithms are specified precisely enough that all implementations must produce identical results:
- Content hash: SHA-256 of ECF-encoded
{type, data} - Signature: Ed25519 sign/verify
- Peer ID derivation: hash of public key with type prefixes
- ECF encoding: deterministic CBOR subset ensuring identical bytes
- URI normalization: canonical path representation
12.4. Cross-Implementation Validation
Same entity same hash in Go, Python, and Rust. Same delegation chain same accept/reject decision. The normative algorithms are unambiguous — implementations either agree or one has a bug.
12.5. Stability Under Evolution
The wire format has remained stable throughout the protocol’s evolution. Entity structure has remained unchanged. The two-message model has remained unchanged. What has changed: type definitions, handler conventions, and capability fields. The protocol is the primitives; the type system is extensible within them.
This stability is consistent with the reduction narrative. If the protocol were over-specified, evolution would require breaking changes. If it were under-specified, evolution would require additions. The pattern of type-system growth within a stable protocol structure suggests the primitives are at an appropriate level of abstraction.
12.6. Limitations of Current Evaluation
- No production-scale deployment data
- Performance measurements not yet systematic
- Formal verification (e.g., TLA+ model checking) has not been attempted
13. Discussion
13.1. Irreducibility vs. Minimality
Irreducibility — the property that no primitive can be removed without losing the system — is not the same as minimality — the property that no simpler equivalent exists. We present evidence for irreducibility through the reduction history and the remove-one analysis. We do not claim minimality in a formal sense.
A different decomposition into six different primitives might exist. The claim is narrower: these six resist further reduction, and the combinatorial analysis shows what each contributes. Whether a formal proof of irreducibility can be constructed is an open question.
13.2. The 3+2+1 Structure
The division into informational (E, I, T), temporal (M, X), and spatial (P) primitives is not merely a classification. It explains the dependency structure and suggests something about the nature of the primitives.
The informational primitives exist as pure structure. A complete E+I+T tree could, in principle, contain every structure and every relationship — it is a static, timeless space of typed, addressable, content-verified data. Self-description holds as a structural fact within it.
The temporal primitives introduce change and agency. They operate on the informational structure but do not create it. Emit introduces time (before/after). Execution introduces directed action.
The spatial primitive introduces position and perspective. Every running system operates somewhere, on some device, with some view of the network. P measures how much of this physical reality the system models.
Each domain transition adds something that the previous domain lacked. Whether this three-domain structure is a deep property of information systems or an artifact of this particular decomposition is a question we leave open.
13.3. Information Before Computation
The observation that E+I+T precedes E+I+T+M+X in the build-up — that information structure exists before computation — is worth examining.
Content-addressed entities exist independently of the processes that create or consume them. An entity’s identity is derived from its content, not from when or how it was produced. The structural truths of E+I+T — self-description, the fixed point, verifiable references — hold without any computation being performed.
This goes further than the familiar observation that data exists before programs act on it. Computation itself, viewed as a mathematical structure — a mapping from inputs to outputs — is information. Such a mapping is a set of (input, output) pairs, a mathematical object rather than a process. In E+I+T, every such mapping could in principle exist as structure. A pure function is a lookup in an (infinite) table.
Computation-as-activity — the temporal process of evaluating a function — exists because the complete table is infinite. We must construct specific entries on demand, and this construction requires time (M) and agency (X).
The purity boundary in the protocol makes this structural: hash references point to content that exists eternally (by content address), while path references point to state that depends on when you look. This distinction arises from content addressing, not from language design.
This observation is explored further in The Entity Church Architecture and Information as Substrate.
13.4. Identity as the Architectural Divide
The choice of how identity is derived is the fundamental architectural axis separating distributed information systems into two qualitatively different camps. The choice has only two stable settings: identity is assigned (a sequence number, UUID, surrogate key, or other externally-issued token) or identity is content-derived (a hash of the entity’s bytes or canonical form).
The database tradition — relational stores, document stores, key-value stores — almost universally selects assigned identity. Rows have keys issued by the system; documents have IDs assigned by the application; records have surrogate primary keys. The identity-assignment authority is internal to the system. Two databases storing the same content produce different identities; the same database can replace a row’s content while preserving its identity.
The content-addressed tradition — Git, IPFS, the entity system — selects content-derived identity. The same bytes produce the same identity, everywhere, always; different bytes produce a different identity, always. There is no identity-assignment authority; identity is a fact about content. Replacing a row’s content produces a different entity, with a different identity; the original is unchanged because it cannot be changed.
This choice is architectural rather than incremental. It cannot be made gradually or partially: a system either commits to content-derived identity and accepts the consequences (immutability, deduplication, verifiability, cross-peer agreement, the cascade catalogued in Convergent Evolution), or it commits to assigned identity and accepts the opposite consequences (mutable rows in place, external deduplication, authority-bound verification, assignment coordination as the path to cross-system agreement). Hybrid designs that assign identity for some entities and derive identity for others exist (most object stores do this), but the database’s mutable-rows-with-assigned-keys is a deliberate structural commitment, not an oversight.
The remove-one analysis (§Without Identity above) catalogs the technical losses when content-derived identity is removed: deduplication, verification, convergence detection, immutability, cryptographic audit. The architectural reading is that these are not five independent properties that happen to all depend on content-derived identity — they are the characteristic consequences of one design choice. The entity system’s identity is structurally constitutive: every primitive downstream of I (Tree binding, Emit, Execution dispatch, Peer trust) inherits assumptions that hold because identity is content-derived. A system that adopts assigned identity is making the opposite commitment everywhere it propagates.
This does not mean content-derived identity is “better.” Assigned identity has real benefits — the data-management tradition is one of the most successful in computing precisely because assigned identity supports mutable rows, denormalization, indexed scans over external fields, and human-readable keys. The architectural-divide claim is only that the choice is binary at the substrate level and reshapes everything above it; mixing the two requires a bridge (the integration layer between an object store and a relational database, for example) that is itself non-trivial design. The companion paper Convergent Evolution catalogs sixteen prominent systems sitting one move off the entity-system substrate, all on the Identity axis specifically — the data-management tradition arriving at this boundary by deliberate design.
13.5. Universal Substrate
A consequence of covering all six primitives: the entity system functions as an intermediate representation across multiple dimensions simultaneously.
| Dimension | What maps in |
|---|---|
| Compute model | Any model represented as typed data, processed by fixed evaluators |
| Type system | Language type systems map to entity types |
| Execution model | Sync, continuation, reactive — exhaust temporal relationships |
| Implementation | Handlers in any language; opaque inside, entity-native at the boundary |
| Protocol | Any protocol maps to EXECUTE dispatch |
| Information system | Any system maps to a primitive subset |
The pattern: the six primitives define a boundary. Everything inside the boundary — typed data, content-addressed, in the tree — inherits all architectural properties: versioning, identity, self-description, audit, convergence, authorization. Everything outside — handler internals, native code — is opaque. The boundary is the EXECUTE interface: typed parameters in, typed result out, capability verified, emit pathway available.
Systems with fewer primitives have narrower boundaries. Git (I+T) bridges content-addressed data but not typed dispatch. gRPC (E+X) bridges typed operations but not content-addressed state. The full six defines a boundary broad enough for everything to cross it.
Whether this is a designed feature or a structural consequence of covering the full primitive space is itself an interesting question. We lean toward the latter — it appears to follow from the primitives rather than from intentional engineering — but this is an observation, not a proof.
13.6. Substrate Floor, Feature Space Above
The six primitives are the substrate of the entity system: the floor a participating peer cannot get below without losing the system. They are not the feature space a developer or application designer works within. The application-architecture level — where one would inventory features, build applications, or compare what two deployments can do — sits above the substrate, populated by extensions.
The extension architecture described earlier is what populates that feature space. The substrate-bridge extensions add reactive computation, version coordination with peer sync, subscriptions, durable workflow, queries, content distribution, transition history, time, and value-level type constraints by registering handlers, types, and emit consumers without modifying the core protocol. An application configures which extensions it relies on (substrate-bridge plus the operational extensions it needs for its deployment), which handlers it installs, and which types it exchanges; another application carrying a different selection looks different at the feature level while sharing the same substrate.
This distinction matters for reading the irreducibility argument correctly. Remove-one is a substrate claim: removing any one of the six leaves a substrate that cannot host the rest. It is not a feature-completeness claim. A working application’s effective feature set is the substrate plus the specific extensions it carries. The six primitives constrain what is possible above them; they do not exhaust it. Conflating the substrate with the feature space — treating six primitives as either over-claimed maximality or under-claimed scaffolding — misreads what each level is doing.
13.7. Particular Instantiation and Interoperability
An important clarification: the pair-relationship graph is a mathematical object, and our core protocol is our particular specification of it. The graph is universal (any distributed information system must contain it); the specification includes specific concrete choices — Ed25519 for signatures, SHA-256 for content hashes, a CBOR subset for deterministic encoding, a specific connection handshake, a specific capability-token structure. These are not additional primitives but instantiations: any implementation could in principle choose differently and satisfy the same structural claims, but two implementations that make different concrete choices would not be interoperable.
This distinction matters for what the framework claims. Mathematical structural coherence — the fact that a system reduces to the six primitives and their pair-relationships — is analytically valuable. It explains why properties emerge, where engineering concentrates, and what changes have large blast radius. It is not, however, a free interoperability mechanism. Two systems that both reduce to the same are not thereby able to exchange entities; they may differ on hash function, encoding, signature scheme, or connection protocol. Interoperability emerges from agreement on concrete choices, not from shared mathematical structure. The Go, Python, and Rust implementations of the entity system interoperate because they conform to identical concrete choices, not because they share a reduction.
This is why the core protocol specification is not minimal. Pure minimalism — “six primitives, agree on a hash function and encoding and signing algorithm, done” — would be unimplementable. The specification includes structural requirements (what the primitives are and how they depend on each other), structural instantiation (the specific concrete choices that make the primitives usable), and some operational conventions (common vocabulary for system handlers and type definitions). All three kinds of content live in the core; the distinction between them is pedagogical and useful for spec work but does not mean “instantiation” or “convention” content could be moved outside without loss.
13.8. Self-Bootstrap and Transferable Functionality
The core protocol exhibits a self-bootstrapping property common to universal substrate designs: the mechanism for acquiring new functionality is itself built from the same primitives that define the core. Handlers are entities at tree paths; installing a handler is ordinary emit (Store the entity, Bind the path); dispatching to a new handler is an ordinary tree walk. Nothing in the extension-acquisition mechanism sits outside the primitive substrate.
This puts the entity system in a family of self-bootstrapping architectures: Lisp is self-extensible because macros and eval make code first-class data; DNA is self-replicating because the replication machinery is encoded in DNA; the metacircular evaluator (Abelson and Sussman 1985) implements a Lisp interpreter in Lisp. In each case, the substrate is sufficient to describe its own evolution mechanism. The entity system’s core protocol is sufficient to describe its own extension mechanism.
A practical consequence: the native platform code required to participate in the system is small. A peer needs to natively implement the bootstrap evaluator (for entity-native computation), primitive I/O operations (read/write, send/receive), and a minimum set of spec-fixed natives (one hash function, one canonical encoding). Estimated at a few hundred lines of platform code per language. Everything else — type definitions, handler implementations expressed as computation, extension logic, domain code — is structurally expressible as entity-native computation and therefore transferable between peers as data. Entity-native computation is Turing-complete, so any computable function (including hash functions, validators, encoders, and domain handlers) can in principle be received as data and evaluated locally, with JIT compilation bridging the performance gap.
This does not mean everything is in practice transferred over the wire: current implementations ship many functions natively for performance. But the structural claim is significant: the entity system is a small native bootstrap plus an arbitrarily large transferable genome of entities and entity-native expressions. The peer-to-peer exchange of extensions and domain code is thus not a bolted-on feature but a direct consequence of the substrate’s design.
The Transferability Classification
The native-bootstrap-plus-transferable-genome split divides system content into four structural classes. Companion papers reference these as the transferability classification:
- Class N (platform-native). Code that each peer must implement natively for the architecture it runs on: the bootstrap evaluator, primitive I/O, OS interfaces. Not transferable between peers with different native architectures. Approximately a few hundred lines per language.
- Class S (spec-fixed natives). Standardized algorithms each peer implements identically per platform: the hash function, the canonical encoding, the signature scheme. Implemented natively for performance but specified to produce identical outputs everywhere. The interoperability surface.
- Class T (transferable data). Everything expressible as entity-native data and computation: type definitions, handler implementations expressed as compute expressions, capability tokens, extension logic, domain content. Transferable between any two peers that agree on the evaluator specification.
- Class B (bridge). The compute extension’s evaluator is the structurally privileged native implementation that makes Class T transferability work. Each peer needs a native Class B implementation; once present, Class T data is executable. Class B sits between Class N (native) and Class T (transferable) and is the structural reason the genome can be exchanged at all.
The classification is descriptive, not normative: where a given function sits on the gradient depends on implementation choices. The Class N / Class B footprint is small by design; the Class T surface is intended to be the bulk of system content. The classification appears in The Entity Church Architecture (computational substrate), The Entity Machine Boundary (the compilation gradient as the path from Class T to Class N), The Universal Computational Genome (the biological analog: ribosome plays the Class B role), DEOS (peer-deployment implications), and Information as Substrate (the philosophical reading).
13.9. Language Agnosticism
A related and distinctive property: the entity system is language-agnostic at the host level. The protocol defines wire format (CBOR-encoded entities), dispatch semantics (EXECUTE in, typed result out), and capability mechanics — all as data, not as code in any particular language. Handlers sit on the far side of the EXECUTE boundary; their internals are opaque to the protocol. A handler can be written in Go, Rust, Python, or any language whose runtime can process entity-typed parameters and return entity-typed results.
This distinguishes the entity system from designs that embed themselves in a specific language or language ecosystem. Lisp defines itself in Lisp. Urbit defines applications in Hoon over Nock. Holochain expresses validation logic as Rust embedded in DNA. Erlang/OTP is an Erlang runtime; the BEAM VM is Erlang-specific. Even the JVM, which hosts multiple source languages, requires JVM bytecode at its core. In each case, participation in the system requires adopting the system’s language substrate.
The entity system’s host-level language agnosticism comes from three structural features combined:
- Protocol is data. Entities are CBOR-encoded; handlers receive typed parameters, not function calls in a specific language.
- Handlers are opaque. The protocol sees only the EXECUTE surface — the interface — not the code behind it.
- Transferable computation is expression data. When computation is expressed as entity-native expressions (the compute extension’s bootstrap types), any peer implementing the agreed evaluator produces identical results.
The three implementations (Go, Python, Rust) exist because nothing in the protocol requires them to share a runtime. Each is an independent native bootstrap; they interoperate because they conform to identical concrete choices (hash function, encoding, signature scheme), not because they share infrastructure. The SDK layer provides language-idiomatic ergonomics per language (builders in Rust, functional options in Go, context managers in Python) over the same underlying protocol operations.
A qualification: the agnosticism is at the host level, not at the computational-substrate level. Entity-native computation — the bootstrap expression types (lambda, apply, if, let, lookup, literal) and their reduction semantics — is itself a particular design choice. It happens to be a lambda-calculus-shaped substrate; other designs (tree calculus, combinator calculus, a different set of primitive forms) could fill the same structural role. Two peers that both implement the core protocol but choose different evaluator designs would share wire format and dispatch but not share transferable computation. The transferable genome is transferable only to peers that agree on the evaluator’s specification, just as the core protocol is interoperable only between peers that agree on hash function and encoding.
In framework terms, the evaluator’s bootstrap-type design is another category (b) structural instantiation: a concrete choice made to realize a structural role (in this case, “a universal computational substrate over content-addressed data”). It is no more universal than SHA-256 is the only hash function; it is the specific evaluator we have settled on. What is universal is the structural role — any distributed information system with all six primitives must settle some universal evaluator to have a transferable computational layer. Our choice is one workable settlement.
Language agnosticism is therefore a practical consequence of the transferability claim given agreed concrete choices: if two peers agree on the core protocol’s instantiation (category b) and on the evaluator’s design, then the genome is transferable between them regardless of host language. The entity system does not have a “native host language” because it does not need one. It does have a “native computational substrate” because computation across peers requires a shared evaluator. Both these commitments — concrete protocol choices and a specific evaluator — make interoperability possible; neither is structurally forced by the six primitives.
13.10. Limitations
Several limitations should be noted:
- No formal verification. The irreducibility analysis is structural and combinatorial, not a mathematical proof. TLA+ model checking or other formal methods are natural next steps.
- No production-scale evaluation. The implementations validate correctness but have not been tested at scale.
- Streaming data. Content addressing requires fixed content for hashing. Continuous streams require discretization into entities — a genuine tension that the current framework does not fully resolve.
- Combinatorial analysis is empirical. The build-up sequence and remove-one test are systematic but not exhaustive. There are subsets; we examine the build-up path and six removal cases.
- Landscape claims rest on analyst-interpreted scoring. The mapping of existing systems onto the six primitives and their partial levels is documented judgment, not automated measurement. The cross-corpus survey informs the pattern claims here, but the named anchor cases are illustrative rather than statistical evidence. Corpus expansion would refine specific cluster boundaries without altering the structural decomposition; the full landscape application is developed in Convergent Evolution and the underlying structural methodology in A Structural Methodology for Information System Domains.
- 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 — the text, code, and design refinements are generated rather than directly authored. This shapes the methodology described in The Entity Core Protocol (particularly the patience for refactoring and the multi-implementation tempo it makes tractable) and is a real factor readers should weigh when evaluating the work.
14. Conclusion
We have described six primitives for distributed information systems — Entity, Identity, Tree, Emit, Execution, and Peer — and examined what properties emerge as they compose.
The build-up sequence reveals a progression:
| Composition | What emerges |
|---|---|
| E+I+T | Self-description, fixed-point types |
| E+I+T+M | Mutability, structural versioning, audit potential |
| E+I+T+M+X | Computation, dispatch, reactive cascades |
| E+I+T+M+X+P | Distribution, capabilities, trust boundaries |
Existing systems map to subsets of two to four primitives. The gaps correspond to properties they lack. We have not found a system that implements five or more.
The protocol was found by alternating construction and reduction: each cycle built mechanisms to handle the next concern, then removed what the entity model could absorb. The substrate revealed itself when further reduction stopped finding anything to remove.
The substrate-bridge system extensions compose through the same six primitives, covering messaging, reactive computation, version coordination with peer sync, subscriptions, durable workflow, queries, content, history, time, and value-level type constraints. Operational, first-pass-grounding, and exploratory extension tiers sit alongside them at distinct structural roles. No extension required modifying the core.
Several questions remain open:
- Can a primitive be removed without losing the system? Our remove-one analysis says no, but a more creative restructuring might find a way.
- Can a seventh primitive be shown to be independently necessary? We have not found one, but absence of evidence is not evidence of absence.
- Can the irreducibility be formally proved? The structural analysis is suggestive but not a proof.
- What are the performance characteristics at scale? The implementations validate correctness but have not been stress-tested.
Companion papers examine the protocol specification (see The Entity Core Protocol), the computational architecture (see The Entity Church Architecture), and the convergent evolution of existing systems toward these primitives (see Convergent Evolution).
We develop a notation for partial primitive levels — fixed evaluators, open dispatch, and other gradients — in the Partial Primitives section below.↩︎
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.
Dimensional Completeness: Validating Protocol Design Through Irreducible Primitives
How do you know a protocol’s type system covers what it needs to? How do you know its capability system is complete? We describe a design validation procedure — analyze the landscape of existing systems in a design space, identify the irreducible primitives that any system must address, decompose each primitive into partial levels, and test whether the protocol covers them. We apply the procedure to two design spaces within the entity core protocol. In type description, analysis of 16 independent type systems finds eight irreducible primitives: naming, shape, cardinality, constraint, composition, equivalence, representation, and evolution. Systems with highest coverage are schema systems (Avro, Protobuf, Cap’n Proto) — the entity type system’s closest relatives. Gaps fall into three categories (type computation, encoding-specific, domain-specific), each excluded by design. In authorization, analysis of capability and access control systems finds eight irreducible primitives: subject, mechanism, verb, object, context, authority, attenuation, and revocation. The entity system covers all eight at high partial levels. A notable convergence: the protocol spec (§5.2) independently arrived at exactly the subject/authority/attenuation distinction by debugging cross-peer capability flows, while a structural decomposition of the design space arrives at the same three primitives by irreducibility tests. Both routes converge. A cross-compilation partition — uniform across Rust, Haskell, TypeScript, C, and Python — independently validates that the type system captures a natural abstraction level. The type primitives ground in the informational primitives (E+I+T); the capability primitives ground in the full set. This paper was first authored before the structural methodology of A Structural Methodology for Information System Domains crystallized; an appendix records the reconciliation and how the primitive list grew from seven to eight under formal analysis.
1. Introduction
A protocol that changes after release imposes migration costs on every implementation and deployment. If specific design choices can be validated before release — if the type system can be shown to cover the structural primitives of data description, and the capability system can be shown to cover the structural primitives of authorization — then the protocol resists the kind of post-release changes that are most expensive: structural ones.
This paper applies a design validation procedure to two design spaces within The Entity Core Protocol: the type system and the capability system. The procedure is the same in both cases: survey existing systems in the design space, identify the irreducible primitives that any system in the space must address, decompose each primitive into partial levels, categorize any gaps, and test whether the protocol covers the space.
The entity core protocol is built from six substrate primitives — Entity, Identity, Tree, Emit, Execution, and Peer — described in The Entity System. These substrate primitives and the fifteen pair-relationships they produce determine what properties the protocol has. But the substrate primitives alone do not tell you whether the type system’s field vocabulary is sufficient, or whether the capability grant’s four fields are the right four. Those are specific design choices that require specific validation against the primitives of the relevant surface design space.
Two independent analyses — one examining type systems, the other examining capability and authorization systems — each find eight irreducible primitives. Each primitive decomposes into 3–6 partial levels. The analyses were conducted by examining existing systems, not by deriving from the entity substrate primitives. The results map back: each surface primitive requires specific pair-coverage among the substrate primitives. The type primitives require pairs within the EIT (self-description) triangle; the capability primitives span the EIT, TMX (reactive dispatch), and IXP (cryptographic capability) triangles. This convergence between bottom-up analysis of an existing design space and top-down structure from the substrate primitives provides confidence that the protocol’s design choices cover what they need to.
A third validation — the cross-compilation partition — examines what happens when programming language features are translated to entity computation. The partition into three categories is uniform across five languages with radically different type systems, suggesting the entity type system captures a natural level of abstraction.
A note on this paper’s history. This paper was first authored before the structural methodology of A Structural Methodology for Information System Domains crystallized. The early work captured the right intuition — survey the landscape, extract the primitives, ground them in the substrate — but using coarser vocabulary (“dimensions”), implicit irreducibility tests, and no formal partial-level decomposition. The methodology, later formalized and applied across roughly twenty domains, was applied back to this paper’s two design spaces under formal procedure. The result: minor refinements for the type system (one additional primitive, three renames) and substantive refinements for the capability system (two additional primitives, including the Authority primitive that the protocol spec independently arrived at by debugging cross-peer capability bugs — §5.2 “three slots”). The appendix records the reconciliation in detail.
The primitive combinatorial analysis — partial levels, pair-coverage scoring, attractor states, and landscape positioning across the entity substrate itself — is developed in the companion paper on Convergent Evolution. The full methodology of structural domain analysis is in A Structural Methodology for Information System Domains. This paper focuses on validating specific protocol design choices through primitive coverage within two surface design spaces, using pair-relationships as the analytical layer that connects surface primitives to substrate primitives.
Companion papers. The six substrate primitives, fifteen pair-relationships, and five named structural triangles are in The Entity System. The protocol specification is in The Entity Core Protocol. The computational architecture and two-level type architecture are in The Entity Church Architecture. The full landscape analysis with pair-coverage scoring across the substrate is in Convergent Evolution. The structural methodology in full generality is in A Structural Methodology for Information System Domains.
2. Type System Design Validation
2.1. The Question
The entity core protocol defines a structural type system. Type definitions are entities — stored at system/type/* in the tree, subject to the same content addressing and dispatch as all other data (see The Entity System; The Entity Core Protocol). But what fields should a type definition have? What structural vocabulary is sufficient for describing data exchanged between peers?
These are not questions the primitives answer directly. The primitives establish that types are entities (E), types have content-derived identity (I), and types live at known paths (T). But the specific structural vocabulary — which fields, which composition mechanisms, which constraints — is a design choice. To validate it, we examine what existing type systems do.
2.2. Eight Primitives of Type Description
Analysis of 16 independent type systems — spanning schema systems, programming languages, and data description formats — reveals eight irreducible primitives that any type system addresses. (Earlier work, before the structural methodology of A Structural Methodology for Information System Domains crystallized, listed seven “dimensions”; the methodology’s formal procedure — explicit irreducibility tests on the landscape, plus partial-level decomposition — surfaces Naming as a separable primitive that the earlier survey took for granted, and clarifies three other primitives via partial-level analysis. See appendix.) Each primitive addresses a structural question that any system exchanging structured data must answer. Each also requires specific pair-coverage over the entity system’s substrate primitives — pairs of substrate primitives that must be in full expressiveness for the surface primitive to operate (see The Entity System).
| Primitive | Question | Required pair-coverage |
|---|---|---|
| Naming | How is a type referenced? | ET (type definitions at known tree paths) |
| Shape | What structure does the data have? | EI (typed content-addressed units) |
| Cardinality | How many of each field can appear (optional, repeated, exactly-k)? | EI (field specifications in types) |
| Constraint | What values are valid within a shape? | EI + ET (validation rules at known paths) |
| Composition | How do types combine and reference each other? | EI + IT + ET (the full EIT triangle) |
| Equivalence | When are two types the same? | EI; IX if runtime equality check; Full I for content-derived |
| Representation | How does the type map to bytes? | EI (hash defined over canonical encoded bytes) |
| Evolution | How does the type change over time? | ET + IT (type versioning in tree) |
Each primitive is irreducible: removing any one loses expressiveness that no combination of the others recovers.
Shape without constraint can describe structure but cannot validate values. Constraint without shape can validate values but has no structure to attach them to. Composition without naming can relate types only by inline embedding, which collapses into Shape. Equivalence without representation can compare by nominal labels but cannot establish cross-system agreement on canonical content. Representation without evolution can serialize data but cannot handle format changes. These are independent axes.
The derivation is forced by the nature of structured data exchange. Data has shape. Shape has fields. Fields have cardinality. Fields have value constraints. Types compose. Types need names. Types need equivalence rules. Types cross wire boundaries (representation). Types change (evolution). Each step follows from the previous. The structural vocabulary is not arbitrary — it is what any system must address when describing data for exchange.
All eight primitives require pairs within the EIT triangle (the self-description triangle from The Entity System). Composition requires the full triangle (all three pairs at full strength); other primitives require specific sub-pairs. The concentration of all eight type primitives within a single named substrate triangle is itself a structural finding: type description is the informational substrate at work, and the EIT triangle is precisely what activates when the informational substrate is complete. A system that does not reach the full EIT triangle will fail to support at least one type primitive; this is predictive and testable.
Partial levels
Each primitive decomposes into partial levels — a gradient from absent to fully elaborated (see A Structural Methodology for Information System Domains). Three excerpts illustrating the pattern (see the methodology domain analysis for the full eight-by-five table):
- Naming: Nm0 anonymous structural types only / Nm1 type aliases / Nm2 first-class named definitions / Nm3 namespaced names (packages, modules) / Nm4 globally addressable names (URI / hash / DID — the entity system’s level).
- Equivalence: Eq0 no equivalence rule / Eq1 nominal (same name) / Eq2 structural (same shape) / Eq3 content-derived (same canonical bytes / hash). Phase transition at Eq2→Eq3: requires the substrate’s Identity primitive at Full I.
- Representation: Rp0 in-memory only / Rp1 single encoding / Rp2 multiple encodings / Rp3 canonical encoding (deterministic single canonical bytes) / Rp4 self-describing encoding (decode without external schema).
The phase transitions matter for the entity system’s distinctive contribution: Eq3 requires Rp3 plus substrate-Identity, and this cascade is what makes type identity intrinsic across peers without coordination.
2.3. The 16-System Comparison
We compared 16 type systems across the eight primitives, scoring each system’s partial level per primitive. Two scoring views are reported: a per-primitive partial-level matrix (full detail in the methodology domain analysis) and an aggregate static-coverage figure for backward continuity with the original analysis.
The aggregate static coverage figures (percentage of the primitive space each system covers with its built-in mechanisms, ignoring type-level computation). These are not summed from the partial-level matrix; each is an analyst estimate of the share of that system’s type-description features that map directly onto the entity type system’s built-in mechanisms — features that need the compute extension or are fundamental gaps do not count. They are coarse by construction (rounded to the nearest 5%), reported here only for continuity with the original seven-dimension analysis; the per-primitive partial levels below are the load-bearing measure.
| System | Aggregate coverage | Primary gaps (in 8-primitive terms) |
|---|---|---|
| Avro | ~85% | Equivalence (nominal only); Composition limited |
| Protobuf | ~80% | Constraint (enums only); Equivalence nominal |
| AT Protocol Lexicons | ~80% | Constraint shallow; Evolution conventional |
| Cap’n Proto | ~75% | Constraint (enums only); Evolution additive only |
| IPLD | ~75% | Constraint shallow; Cardinality minimal — but Eq3 via CID |
| CDDL | ~70% | Evolution absent; Naming module-scoped |
| GraphQL | ~70% | Representation (HTTP+JSON convention); Constraint shallow |
| ASN.1 | ~70% | Representation (multiple encodings, less canonicalization); rich Constraint via info objects |
| JSON Schema | ~60% | Equivalence absent; Representation non-canonical |
| Rust | ~60% | Representation (no built-in serialization); Evolution conventional |
| CUE | ~60% | Representation conventional; Evolution conventional — but very strong Constraint via lattice |
| TypeScript | ~55% | Representation (no built-in serialization); Evolution absent |
| SQL DDL | ~50% | Composition (joins, not type composition); Representation per-engine |
| Haskell | ~45% | Representation (no built-in); Evolution absent; high Composition via type classes |
The pattern is similar to the earlier seven-dimension scoring, with one shift: the entity type system’s distinctive Eq3 (content-derived equivalence via canonical encoding) now shows as a partial-level peak rather than as a single binary dimension. Schema systems concentrate at Eq1 (nominal) regardless of how strong their other primitives are; IPLD is the only surveyed schema system reaching Eq3 in any form (via CID-keyed schemas, not content-derived equivalence of values). This sharpens the earlier seven-dimension “entity system exceeds most systems on Identity” claim — now grounded in a specific phase transition (Eq2→Eq3 requiring substrate-Identity at Full I).
Systems with highest aggregate coverage are schema and protocol systems — Avro, Protobuf, AT Protocol, Cap’n Proto, IPLD, CDDL. These systems focus on describing data structure for exchange. They are the entity type system’s closest relatives. In pair-coverage terms, these systems concentrate their coverage within the EIT triangle: strong EI (typed data with identity), strong ET (types at known paths or in known schemas), and strong IT to the extent their schemas are addressable. Gaps reflect incomplete triangle coverage rather than structural absence.
Programming languages score lower not because they are less capable, but because they invest type expressiveness in Composition (Cp4–5: generics, type classes, conditional types) and in type-level computation, rather than in the description primitives the protocol/schema cluster optimizes for. Haskell’s type classes, TypeScript’s conditional types, and Rust’s trait system are Composition mechanisms at Cp4–5. They extend beyond Shape description into program verification, which we treat as a scope-excluded primitive (see Gap Categorization below). When type computation is removed, the underlying description vocabulary is the same: Haskell’s data declarations describe the same Shape space as Protobuf messages. The pair-coverage pattern differs: programming languages activate EX (typed computation) and EI (types as language constructs) strongly but often do not settle on a shared wire-level ET, which is why translating a Rust type to a Protobuf message requires an explicit schema commitment.
2.4. Convergence Evidence
14 of 16 systems independently develop vocabulary for the same structural primitives:
| Structural primitive | Systems that have it | Notable absences |
|---|---|---|
| Scalar types | All 16 | None |
| Records (named fields) | All 16 | None |
| Sequences (ordered collections) | All 16 | None |
| Maps (key-value pairs) | 14 of 16 | SQL (workarounds) |
| Unions (one of several) | 13 of 16 | Protobuf (partial), SQL |
| Composition | 14 of 16 | Varies in mechanism |
| Optionality | All 16 | None |
No system achieves data shape description with a structurally different vocabulary. Systems that appear different — CUE’s lattice-based types, Haskell’s algebraic data types, SQL’s relational model — decompose to the same structural primitives when the type computation layer is removed. The structural convergence across 16 independently designed systems is strong evidence that the vocabulary is not arbitrary.
2.5. Gap Categorization
Every gap between the entity type system and any of the 16 systems falls into one of three categories:
Type computation (intersection types, conditional types, negation types, mapped types, higher-kinded types, information objects): computations over types that produce new types. These are expressiveness that belongs in the compute extension — they extend beyond structural description into type-level programming.
Encoding-specific (field tags and ordinals, zero-copy layout directives, CBOR-specific validation rules, multiple encoding rule sets): properties of particular wire formats. Excluded by design from an encoding-independent type system. ECF (Entity Canonical Form) deterministic encoding means the entity type system is deliberately encoding-independent — bridge handlers translate encoding-specific features when crossing the protocol boundary.
Domain-specific validation (format validators, uniqueness constraints, cross-field arithmetic constraints): domain rules that depend on application context. These belong in handler validation or the type extension’s value-level constraint mechanism, not in the structural type system.
This categorization means the entity type system is complete for structural type description. What it excludes is excluded by design, with a specific mechanism for where each category belongs: type computation in the compute extension, encoding specifics in bridge handlers, domain validation in handler logic.
2.6. Entity Type System Coverage
The entity type system covers all eight primitives, with the following partial-level positions:
- Naming: Nm4 (globally addressable). Types live at
system/type/Xpaths in the tree; type-refs are paths; type identity is intrinsic to the path-and-content pair. - Shape: Sh4–Full Sh. Records, sequences, maps, unions (via
union_of), tuples. Self-describing types (system/typeis itself an entity type). - Cardinality: Ca2–3. Required, optional, repeated. Open types preserve unknown fields for forward compatibility. Richer cardinality (uniqueness, exactly-k) in the type extension.
- Constraint: Co2–3 in core, Co3 in the type extension. Pattern validation, range constraints, enumerations at core; cross-field arithmetic in the extension’s value-level constraint mechanism. Co4 (refinement / dependent constraint) is scope-excluded by design.
- Composition: Cp3–4. Single inheritance (
extends), entity references via content hashes, generics, union types. Cp5 type-level computation is scope-excluded from the type system itself and lives in the compute extension. - Equivalence: Eq3 (content-derived). Same canonical bytes hash to the same identity everywhere. The distinctive entity-system contribution; depends on Rp3 + substrate-Identity at Full I.
- Representation: Rp3 (canonical). ECF (Entity Canonical Form) gives encoding-independent structural description with deterministic canonical bytes. Self-describing types support an Rp4-like behavior (decoders can resolve type definitions via tree paths).
- Evolution: Ev2–3. Open types, compatibility rules, deprecation in core. Dynamic aspects (schema migration, live type evolution) distributed across extensions.
The two-level type architecture described in The Entity Church Architecture maps onto these primitives: Level 1 (structural types, core protocol) covers Naming, Shape, Cardinality, Composition, Equivalence, Representation, and Evolution. Level 2 (value constraints, type extension) covers Constraint. The separation reflects an observation: structure is universal (every system exchanging data needs to know field shapes), while value-level validation is domain-specific (what counts as valid varies by application).
3. Capability System Design Validation
3.1. The Question
The entity core protocol defines a capability system with four-dimensional grants (see The Entity Core Protocol). Each grant entry has fields for handler scope, resource scope, operation scope, and peer scope. Capability tokens carry these grants with cryptographic attenuation chains, temporal windows, and explicit revocation. The system has been refined across many spec revisions, including the normative addition of “three slots” for cross-peer capability provenance (see below).
But why these particular fields? Are they the right ones? Is the design space complete?
3.2. Eight Primitives of Authorization
Analysis of capability systems, access control models, and authorization frameworks reveals eight irreducible primitives. (Earlier work, before the structural methodology of A Structural Methodology for Information System Domains crystallized, listed seven “dimensions”; the methodology’s formal procedure surfaces two additional primitives — Authority as separate from Subject, and Revocation as separate from Time-expiry — both of which the protocol spec independently arrived at by debugging cross-peer flows. See appendix for the reconciliation.)
Each primitive corresponds to a structural aspect of authorization that any system must address. The primitives operate at three protocol layers (per-grant-entry scope, per-token scope, separate lifecycle mechanism); one primitive (Context) operates across both grant and token layers, giving the natural breakdown below.
Per-grant-entry scope primitives (one field per grant entry in a token’s grants array):
| Primitive | Question | Grant field | Required pair-coverage |
|---|---|---|---|
| Mechanism (Mc) | Via what handler? | handlers |
EX + TX (typed dispatch over tree paths) |
| Verb (Vb) | What action? | operations |
EX (typed handler operations) |
| Object (Ob) | On what data? | resources + exclude |
TX + TP (peer-namespaced paths under dispatch) |
| Context (Cx) | At what peer? | peers (spatial axis) |
TP + XP (peer namespacing and cross-peer dispatch) |
Per-token scope primitives (one field on the capability token itself):
| Primitive | Question | Token field | Required pair-coverage |
|---|---|---|---|
| Subject (Sb) | Who is acting? | grantee (spec §5.2 slot: EXECUTE author) |
IP (content-addressed peer ID, requires Full I) |
| Authority (Au) | Whose permission is being exercised? | granter (spec §5.2 slot: resource owner / chain root) |
IP + IX (signing authority, requires Full I) |
| Attenuation (At) | How is power narrowed in delegation? | parent; chain construction (spec §5.2 slot: in-chain granters) |
IX + XP (the IXP capability triangle) |
| Context (Cx) | During what window? | expires_at, not_before (temporal axis) |
IM + TM (both axes of emit carry temporal ordering) |
Lifecycle mechanism (operates outside the token via separate entity):
| Primitive | Question | Mechanism | Required pair-coverage |
|---|---|---|---|
| Revocation (Rv) | How is power removed? | system/capability/revocation; is_revoked algorithm (spec §“Revocation model”); EXTENSION-ROLE 401 capability_revoked |
IT + TM (revocation entities at paths, emit-propagated, fail-closed) |
Context (Cx) operates at both grant and token layers because the design space has both a spatial scoping axis (which peers) and a temporal scoping axis (which time window), and the methodology treats them as partial-level axes of one Context primitive rather than as two separate primitives. The architecture team’s choice to express the spatial axis per-grant (peers field) and the temporal axis per-token (expires_at, not_before) is a structural design choice within Context, not a difference in primitive identity.
An extensibility escape hatch — the constraints field — allows domain-specific coordinates without adding primitives.
Three primitives require Full I to activate (Sb, Au, At) because their supporting pairs (IP, IX) are phase-transition pairs: they do not operate at partial identity levels (see The Entity System). A system at I1 (assigned identity, not content-derived) cannot express these primitives in the entity-system sense, regardless of how many grant fields it has. This is the structural reason capability-based security in the entity system requires Full I and not merely some form of identity.
3.3. The Three-Slot Convergence (Spec ↔︎ Methodology)
The Subject/Authority/Attenuation distinction is the most consequential refinement in the eight-primitive analysis, and it has a notable provenance: the architecture team and the structural methodology arrived at the same three-slot decomposition by entirely independent routes.
The spec route was operational. §5.2 (“Cross-peer capability provenance — the three slots”, normative) was added after a recurring class of cross-peer capability bugs in which the local case of authorization (where the requester, the resource owner, and the in-chain granters collapse onto one identity) silently omitted two of the three slots. Cross-peer flows force the slots apart, and code paths reasoned about only the local case mis-attributed authority. The amendment names the three slots — and pins each to a different check point. In the spec’s own words:
A capability presented in an EXECUTE has three independent identity slots, each checked at a different point. […]
- Root — the peer that owns the resource being acted on. A chain can authorize action on peer X’s resource only if it roots at an authority X conferred. […]
- Grantee (of the leaf) — the wielder: the identity that authors the EXECUTE. […] The cap must be granted to whoever presents it.
- In-chain granters — every party that attenuated along the way, including any installer/minter that pre-mints a cap for later use. […] requires only that the writer appear as a granter somewhere in the chain — not that the chain roots at the writer.
—
ENTITY-CORE-PROTOCOL§5.2
That the three slots are checked at three different points is the operational payoff: it is exactly the structure that the local case hides. §5.2 makes the slots an enforced invariant — any cross-peer capability-bearing operation must fill all three explicitly — and EXTENSION-SUBSCRIPTION §1.2 and EXTENSION-CONTINUATION §4.2 case 3 are now framed as instances of this one model, not as independent designs.
The methodology route was theoretical. The structural decomposition of capability-systems-as-a-domain (per A Structural Methodology for Information System Domains, the canonical analysis is under the project’s methodology directory) tests primitive candidates by irreducibility, compositional productivity, and empirical recurrence. The candidate primitive set for authorization includes Subject (the requester at request time) and Authority (the source of permission). They are independent: every delegated grant has a Subject distinct from its Authority, and the cap-systems literature (Dennis & Van Horn 1966; Miller 2006) treats them as separate concepts.
Both routes arrive at the same decomposition: Subject (grantee), Authority (chain root), Attenuation (in-chain granters). The convergence is structural evidence: the decomposition is not an artifact of either route. It is what the design space requires.
3.4. Why Each Primitive Is Irreducible
Removing any primitive loses authorization expressiveness:
- Without Subject: cannot distinguish who is acting. Every request is anonymous.
- Without Mechanism: cannot scope by handler. Authorization is mechanism-blind.
- Without Verb: cannot distinguish read from write from delete. All operations are equivalent within a mechanism.
- Without Object: cannot scope by data. Authorization is all-or-nothing on data access.
- Without Context: capabilities are unconditional — no time bounds, no spatial scoping, no environmental conditions.
- Without Authority: cannot answer whose permission is this exercising; every capability appears equally valid; cross-peer authorization collapses.
- Without Attenuation: capabilities cannot be safely delegated; every grant must come from root with full power.
- Without Revocation: capabilities are eternal — expiry without revocation handles only foreseeable cancellation, not compromise or policy change.
Each is an independent axis. Mechanism and Verb are distinct because the same verb (e.g., “read”) may be authorized on one mechanism but not another. Object and Context are distinct because the same object path may be accessible in some contexts but not others. Authority and Subject are distinct in any delegated grant (the holder of the capability is not its root). Attenuation and Revocation are distinct temporal modes: Attenuation is forward-narrowing at delegation time; Revocation is backward-cancellation after grant.
3.5. Capability as Region
A capability token is not a point in the eight-dimensional space — it is a region. Each grant entry defines a volume in the per-grant primitives: a set of mechanisms, a set of objects, a set of verbs. The token adds Subject, Context, Authority, and Attenuation constraints. Revocation can subsequently reduce the volume to zero.
Authorization is checking whether a point (the current request) falls within the region (the capability token) and the region has not been revoked. Attenuation is creating a sub-region — every attenuated capability is a smaller volume within the parent. The volume can only shrink, never grow. This is monotonic attenuation: delegation can restrict but never amplify. Revocation is a discrete event: the volume goes from positive to zero on a specific token.
3.6. The Four-Dimensional Grant Within an Eight-Primitive Structure
The entity system’s grant entry has one field per per-grant-entry primitive:
handlers(Mechanism)operations(Verb)resources+exclude(Object)peers(Context, spatial axis)
This is the original “four-dimensional grant” framing of this paper. It remains accurate as a description of what varies per grant entry. The methodology refinement shows that the four-dimensional grant is one layer in a larger eight-primitive structure: four per-grant scopes inside a token that itself carries four additional primitives (Subject as grantee, Authority as granter, Attenuation via parent chain, Context-temporal via expires_at / not_before), with Revocation operating as a separate lifecycle mechanism (system/capability/revocation).
Counting the layers: 4 per-grant + 4 per-token (where Context appears at both layers as different partial-level axes) + 1 lifecycle = the 8 primitives. The earlier framing of this paper called the per-grant set “the four-dimensional grant” and treated the remainder as “Subject + Time + Delegation” — which collapsed Authority into Subject and bundled Revocation into Time. The methodology view separates these correctly and adds Revocation as a first-class lifecycle primitive.
The four-dimensional grant is therefore a principled and correct architectural choice for what varies per authorization scope; the methodology refinement is to the enumeration of what surrounds the grant, not to the grant itself.
3.7. Comparison to Existing Systems
Five capability and authorization systems illustrate different coverage patterns. Each system is scored at the partial-level of each of the eight primitives (per the methodology analysis).
| Primitive | Entity System | Zanzibar | UCAN | Macaroons | Biscuit | CHERI |
|---|---|---|---|---|---|---|
| Subject (Sb) | 4 (content-addr) | 2–3 (user-id) | 4 (DID) | 1–2 (bearer) | 2 (bearer+attested) | 2 (process) |
| Mechanism (Mc) | 3 (handler-open) | 1 (service) | 1 (cap scope) | 1 (service) | 1 (service) | 0 (mem-bound) |
| Verb (Vb) | 3 (extensible) | 2 (CRUD-ish) | 2–3 (abilities) | 2 (caveats) | 3 (Datalog) | 1 (load/store) |
| Object (Ob) | 5 (set-theoretic) | 3 (per-object) | 3 (URI) | 1 (service-implicit) | 2–3 (Datalog) | 3 (mem region) |
| Context (Cx) | 3 (time + peer) | 1 (req-time) | 2 (nbf/exp) | 2 (time + caveats) | 2–3 (Datalog) | 0 (no env) |
| Authority (Au) | 3 (per-peer root) | 1 (central) | 3 (per-DID) | 1 (per-service) | 1 (per-token) | 0–1 (system) |
| Attenuation (At) | 3 (composing) | 0–1 (relations) | 2–3 (proof chain) | 3 (caveats) | 3 (third-party) | 3 (sub-cap) |
| Revocation (Rv) | 3 (push-revoke) | 2 (delete tuple) | 1 (expiry) | 1 (expiry) | 1 (rev-id) | 2 (invalidate) |
The entity system reaches the highest partial level on six of eight primitives. UCAN matches Sb4 (both use content-addressed identity); CHERI matches At3 (sub-capability derivation in hardware); none of the surveyed systems reaches Ob5, Cx3-with-spatial-axis, or Au3-with-per-peer-root in combination.
The pair-coverage view explains the differences. Each system activates a subset of the capability-relevant substrate triangles:
- Zanzibar activates IP (subject) and TX (resource via relations), concentrated in a single-domain IP+TX cluster. Au1 (central authority) means the IXP triangle does not fully activate.
- UCAN activates IP (DID), EX (ability), and the IX aspect of IXP (proof chains) but not the full IXP triangle (no TP, no XP for topology). Revocation stays at Rv1.
- Macaroons activate IP (bearer), partial EX (caveat-encoded operations), and IM/TM (time caveats), but no TX for resource routing. At3 makes Macaroons attenuation-strong but Au1 limits provenance reasoning.
- Biscuit extends Macaroons’ caveat model with Datalog, reaching Vb3 and richer Cx, but stays at Au1, At3, Rv1.
- CHERI activates capability-as-machine-word with hardware enforcement. At3 (sub-capability derivation) is hardware-implemented. But Mc0 (memory-bound, not mechanism-aware) and Cx0 (no environmental conditions) limit its scope to the per-memory-access level.
The entity system activates the full IXP capability triangle plus TX (handler dispatch), TP (peer-namespaced objects), and IM/TM (temporal context). Authority at Au3 (per-peer roots) requires substrate-Identity at Full I; this is the cascade that lets the entity system reach the highest partial levels across the most primitives in one composition.
This also maps to classical access control theory (ABAC): Subject attributes map to Sb. Action attributes map to Mc + Vb. Resource attributes map to Ob. Environment attributes map to Cx. Meta/policy attributes map to Au + At. Lifecycle management (often outside ABAC’s frame) maps to Rv. The entity system provides finer granularity than ABAC by separating Action into Mechanism and Verb (distinct pair-coverages: TX vs EX), keeping Authority distinct from Subject (the cert-chain framework in Entity System Security Architecture operates on this distinction), and treating Revocation as a first-class lifecycle primitive.
4. Cross-Compilation Partition
4.1. The Partition
When translating any programming language to entity computation, language features partition into three categories (see The Entity Church Architecture):
Category A (maps directly): data types, functions, closures, generics, async, pattern matching, modules, interfaces. These map to entity types, handlers, compute expressions, type parameters, continuation chains, and tree structure.
Category B (erases): lifetimes, ownership, borrow checking, GC internals, access modifiers, stack layout, laziness strategy. Machine-level concerns that the content-addressed substrate handles structurally.
Category C (requires handler embedding): SIMD, inline assembly, memory-mapped I/O, raw pointer arithmetic, hardware register access. These need the actual machine and live inside native handlers, opaque to the entity model.
4.2. Uniformity Across Languages
The partition is uniform across five languages with radically different type systems and runtime models:
| Language | Category A | Category B | Category C |
|---|---|---|---|
| Rust | structs, enums, functions, closures, generics, async | lifetimes, borrowing, ownership, Send/Sync, unsafe | SIMD, inline assembly, FFI |
| Haskell | data types, functions, closures, pattern matching, simple type classes | lazy evaluation strategy, strictness, memory layout | IO monad internals, GHC primops, type families |
| TypeScript | interfaces, unions, functions, generics, async/await | access modifiers, readonly, type narrowing | DOM manipulation, runtime reflection |
| C | structs, enums, functions | pointer arithmetic, manual memory, stack management | inline assembly, hardware registers, signal handling |
| Python | classes, functions, closures, generators, async | GC internals, reference counting, GIL | C extensions, ctypes, memory views |
In every case: Category A represents what the language says about data and its transformation. Category B represents what the language says about the execution substrate — these erase because entity computation is a different substrate. Category C represents machine-level operations that the language exposes.
The entity type system abstracts away the same things across all languages. Rust’s lifetimes, Haskell’s laziness, TypeScript’s access modifiers, C’s pointer arithmetic, Python’s GC — all are Category B. All erase. What survives is the data transformation semantics, and those are universal.
4.3. Category B as Purity Boundary
Why does Category B erase? Consider Rust’s ownership model. It prevents use-after-free, double-free, and data races. In entity computation, none of these problems exist:
- Use-after-free: entities are content-addressed and immutable. Nothing is freed.
- Double-free: there is nothing to free. Content-addressed entities persist.
- Data races: entities are immutable. Path rebindings are serialized through the emit pathway.
Lifetimes compile to nothing. They erase completely. Not because entity computation cannot express them, but because the problems they solve do not exist in a content-addressed, immutable-entity, single-emit-pathway model. The entity computation substrate inherently provides the guarantees that lifetimes enforce in Rust.
The same pattern applies to every Category B feature across every language. Each Category B feature manages an aspect of the execution substrate — memory layout, evaluation strategy, access scope — that the content-addressed model handles structurally. Content addressing provides identity and lifetime semantics. The emit pathway serializes state changes. Open types handle forward compatibility.
4.4. Category C as Handler Boundary
Category C features require machine access. They cannot be expressed in content-addressed typed data because they need the physical machine: specific instruction sets, memory-mapped hardware, operating system interfaces. These live inside native handlers, which are opaque to the entity model — typed parameters in, typed result out, machine access inside.
Category C defines the machine boundary — where entity computation ends and physical computation begins. This boundary is examined in The Entity Machine Boundary.
4.5. Independent Validation
The cross-compilation partition validates the type system from a different direction than the 16-system comparison. The type comparison asks: does the structural vocabulary cover the description space? The cross-compilation partition asks: does the abstraction level capture the right things?
The uniformity of the partition across five languages — the same A/B/C split despite radically different type systems — suggests the entity type system sits at a natural level: above machine computation (Category B erases), below human-level intention (Category A maps), with a clean boundary to hardware (Category C embeds). Entity computation sits above machine computation but below human-level intention. It operates at the level of data transformation and coordination.
5. Connection to Substrate Primitives
The type primitives and capability primitives were identified by examining existing systems — bottom-up analysis within each design space. The six substrate primitives were identified by alternating construction and reduction of the protocol — top-down design (see The Entity System). That the two routes converge through pair-coverage provides independent validation.
5.1. The Four-Layer Analytical Framework
The grounding from substrate primitives to surface primitives is not a single step but passes through an intermediate layer. Four layers of analysis are available:
| Layer | Content | Count |
|---|---|---|
| Layer 1: Substrate primitives | E, I, T, M, X, P | 6 |
| Layer 2: Pair-relationships | pair-relationships with structural load (see The Entity System) | 15 |
| Layer 3: Internal partial levels | Sub-axes within each substrate primitive (see Convergent Evolution) | 19 |
| Layer 4: Surface primitives | Primitives of surface design spaces (type description, authorization) | 16 (8+8) |
The surface-primitive analyses in this paper live at Layer 4. They were identified through formal methodology procedure (see A Structural Methodology for Information System Domains) applied to each design space independently; that they ground cleanly back through Layers 3, 2, and 1 is what “convergent validation” means here. Pair-relationships are the natural intermediate layer: they explain why particular surface primitives require particular substrate primitives, because each surface primitive requires specific pair-coverage to operate.
5.2. Type Primitives Ground in E+I+T via the Information Pair-Bundle
The eight type primitives map to informational substrate primitives, and more precisely to specific pair-coverage:
| Type primitive | Pair-coverage required | Substrate involved |
|---|---|---|
| Naming | ET (type definitions at known tree paths) | E, T |
| Shape | EI (typed content-addressed units) | E, I |
| Cardinality | EI (field specifications in types) | E, I |
| Constraint | EI + ET (typed validation rules at known paths) | E, I, T |
| Composition | EI + IT + ET (entity references over named typed data) | E, I, T |
| Equivalence | EI; IX if runtime equality check; Full I for content-derived | E, I, (X) |
| Representation | EI (hash defined over canonical encoded bytes) | E, I |
| Evolution | ET + IT (type versioning in tree) | E, I, T |
All eight type primitives require pairs within the EIT triangle (the self-description triangle from The Entity System). This is consistent with the observation that information precedes computation: the type system describes structure, which is informational. Constraint enforcement (checking values against constraints) requires computation (X), but the constraints themselves are structural descriptions over the EIT triangle.
5.3. Capability Primitives Ground in the Full Substrate via Multiple Pair-Bundles
The eight capability primitives ground in different substrate primitives and pair-bundles:
| Capability primitive | Pair-coverage required | Substrate involved |
|---|---|---|
| Subject (Sb) | IP (content-addressed peer identity) | I, P |
| Mechanism (Mc) | EX + TX (typed dispatch over tree paths) | E, T, X |
| Verb (Vb) | EX (typed handler operations) | E, X |
| Object (Ob) | TX + TP (peer-namespaced paths under dispatch) | T, P, X |
| Context (Cx) | IM + TM (temporal); TP + XP (spatial) | I, T, M, P, X |
| Authority (Au) | IP + IX (signing authority, the IXP root) | I, X, P |
| Attenuation (At) | IX + XP (in-chain granters and cross-peer chain) | I, X, P |
| Revocation (Rv) | IT + TM (revocation entities at paths, emit-propagated) | I, T, M |
The capability primitives require all six substrate primitives and reach into multiple named triangles: EIT (types-as-tokens), TMX (dispatch + temporal scoping), IXP (capability cryptography), and the temporal axis IM/TM (lifecycle). Together, the 16 surface primitives (8 type + 8 capability) require all six substrate primitives and the five named structural triangles from The Entity System.
5.4. Phase-Transition Pairs Constrain Capability Completeness
Two of the 15 pair-relationships are phase-transition pairs (see The Entity System): they do not activate gradually but require Full I on their Identity endpoint.
- IX (convergence check): requires content-derived identity. Runtime equality of typed outputs depends on Full I.
- IP (content-addressed peer ID): requires Full I to derive a peer’s identifier from a key hash.
These phase transitions matter for capability completeness. Three capability primitives — Subject (via IP), Authority (via IP+IX), and Attenuation (via IX) — do not come in gradations at all; they require Full I to function. A system at I1 (assigned identity) cannot have capability-chain verification in the entity-system sense, even if it otherwise implements every grant field. This is the structural reason the entity system requires Full I: without it, the IXP capability triangle cannot activate, and three of the eight capability primitives degrade.
5.5. Convergence of Analyses
Three observations about this mapping.
First, the type primitives require only pairs within the EIT triangle, while the capability primitives span multiple triangles and require the full substrate. This reflects the 3+2+1 structure of the primitives described in The Entity System: information (E, I, T) is foundational; time (M, X) and space (P) build on it. Data description is an informational concern; authorization is a concern that spans all three domains.
Second, the two analyses were conducted by different procedures, and a third independent route reinforces them. The type analysis surveyed 16 existing type systems and found eight irreducible primitives by structural test. The capability analysis examined capability literature and surveyed five capability/access-control systems and found eight irreducible primitives. The protocol spec, refined operationally by debugging cross-peer capability bugs, arrived at the same Subject/Authority/Attenuation decomposition in §5.2. Three routes (methodology over types, methodology over capability, spec operational refinement) converge on consistent decompositions. None was derived from the substrate primitives or the pair-relationship framework. That all three map cleanly back through pair-coverage and substrate grounding is convergent evidence that the substrate primitive set spans these design spaces.
Third, the pair-relationship layer provides a more precise validation than substrate-level grounding alone. “Composition requires E+I+T” is true but coarse; “composition requires the full EIT triangle” is precise and testable. Systems that cover only part of the EIT triangle (Git has EI + IT but weak ET; Plan 9 has ET + (partial T) but weak EI) would not support composition in the entity-system sense. The pair-coverage view predicts this; the primitive-count view does not.
The full substrate combinatorial analysis — partial levels, internal dimensions, attractor states, and landscape scoring across existing systems — is developed in Convergent Evolution. The methodology that produces surface-primitive analyses of the kind in this paper is in A Structural Methodology for Information System Domains.
6. Discussion
6.1. Design Validation as Procedure
The procedure applied in this paper has general applicability. For any protocol design decision:
- Declare the design space and its type (substrate / surface / bridge / ecosystem / context) (see A Structural Methodology for Information System Domains). The declaration predicts filter stringency and core triad function.
- Survey the landscape: examine existing systems that address the same problem.
- Extract irreducible primitives via three tests: structural minimality (removing forfeits expressiveness), compositional productivity (combinations yield new capabilities), empirical recurrence (shapes design decisions across instances).
- Decompose each primitive into partial levels (typically 3–6 per primitive). Iterate steps 3 and 4 until both the primitive set and partial levels stabilize.
- Identify dependencies, pair-relationships, and load-bearing compositions within the primitive set.
- Categorize gaps: classify any features the protocol does not cover, and determine whether each gap is by design (excluded with a designated mechanism) or by omission.
- Map back to substrate primitives via pair-coverage: verify that each surface primitive grounds in specific pair-relationships within the substrate primitive set. Surface primitives that require substrate pair-bundles the substrate cannot activate signal a missing substrate primitive or missing structural capability.
This is the structural methodology of A Structural Methodology for Information System Domains specialized to design validation. It is not specific to the entity system: any protocol with a type system could survey existing type systems for primitive coverage; any protocol with an authorization model could survey existing authorization systems. The procedure produces structured confidence, not proof — but structured confidence that specific primitives have been checked is more useful than informal intuition about completeness. The pair-coverage step adds precision: “does primitive X require pair-bundle Y?” is a testable question.
6.2. Two Independent Analyses Converging on Eight
Both the type analysis and the capability analysis found eight irreducible primitives. This is a coincidence of count, not of structure — the two sets are entirely different, addressing different design spaces. But the convergence is worth noting: in both cases, the dimensionality is low enough to be tractable (eight, not eighty) and high enough to capture meaningful distinctions (eight, not three).
The pair-coverage mapping shows why both counts land in this range. The type primitives all live within a single named substrate triangle (EIT); eight pair-sub-coverages within one triangle is a natural granularity for data description. The capability primitives span three named triangles (EIT for tokens-as-typed-data, TMX for reactive-dispatch + temporal, IXP for capability cryptography) plus the TX and TP pairs for routing and the IT+TM pair for revocation; eight distinct authorization-relevant coverages across this span is similarly natural. Neither number is an accident of measurement; both reflect the pair-coverage structure required.
The earlier seven-dimension framing in this paper missed one primitive in each design space — Naming for types (taken for granted because every surveyed system has it), and Revocation for capability (bundled into Time/expiry) — and bundled Authority into Subject for capability. The methodology surfaced all three. In the capability case, the protocol spec independently surfaced the Subject/Authority distinction by operational debugging (§5.2), reaching the same decomposition as the methodology by a separate route.
Both results sit as open invitations rather than proofs. A ninth type primitive independent of the eight — a question about data description that does not decompose into naming, shape, cardinality, constraint, composition, equivalence, representation, or evolution, and that does not reduce to pairs already covered within the EIT triangle — would refute the closure claim on type description. A ninth capability primitive independent of the eight — a request attribute or token-lifecycle property that is not subject, mechanism, verb, object, context, authority, attenuation, or revocation, and that requires pair-coverage outside the triangles already named — would do the same for authorization. None has been identified.
6.3. Protocol Stability
The practical outcome of primitive validation is protocol stability. The entity core protocol’s wire format has remained unchanged across many revisions (see The Entity Core Protocol). Entity structure has remained unchanged. The two-message model has remained unchanged. What has changed: type definitions, handler conventions, capability grant fields, and the operational sharpening that produced amendments like §5.2’s three-slot model (which clarified rather than restructured the underlying mechanism). Evolution occurs within the type system and extension architecture rather than requiring protocol changes.
The primitive analyses explain this stability. If the type system covers all eight description primitives (via full pair-coverage over the EIT triangle), there is no structural gap that would force a protocol change. If the capability system covers all eight authorization primitives (via pair-coverage across EIT, TMX, and IXP plus IT+TM for revocation), there is no authorization gap that would force a grant restructuring. Gaps are accommodated by the mechanisms already in place: type computation in the compute extension, encoding specifics in bridge handlers, domain validation in handler logic, additional authorization constraints in the constraints field, revocation in system/capability/revocation. In pair-coverage terms: the triangles are complete, so extensions can operate within them without requiring the core protocol to add new pair-relationships.
6.4. Limitations
Several limitations should be noted:
- Irreducibility is empirical. The arguments that each primitive is irreducible are structural and empirical, not mathematical proofs. A ninth primitive in either design space, or a demonstration that two of the eight reduce to each other, would refute the closure claim; none has been found.
- The 16-system type comparison is not exhaustive. Additional type systems (dependent-type systems, refinement-type systems, effect systems) could be included. We selected systems spanning schema formats, programming languages, and data description languages to cover the space broadly, but gaps in coverage are possible. Dependent-type systems would primarily exercise Cp5 (type-level computation), which is scope-excluded from the entity type system by design.
- Coverage scores are partial-level assessments. The per-primitive partial-level positions are analyst assessments, not measurements. Different evaluators might assign slightly different levels. The relative ordering is more reliable than the absolute levels.
- Capability system comparisons are structural. We compared primitive coverage at the partial-level resolution, not operational characteristics like latency, scalability, or deployment model. Zanzibar’s scalability advantages are real and are not captured by primitive analysis.
- The cross-compilation partition has been validated on five languages. Additional languages might reveal edge cases, though the structural argument (Category B erases because the content-addressed substrate provides equivalent guarantees) applies generally.
- 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 methodology this enables is described in The Entity Core Protocol.
7. Related Work
Type system theory. Pierce (Pierce 2002) provides the foundational treatment of type systems and programming languages. Cardelli and Wegner (Cardelli and Wegner 1985) analyze types, data abstraction, and polymorphism. Our analysis differs in focus: we examine type systems as data description mechanisms for inter-system exchange rather than as program verification mechanisms, which explains why schema systems score higher than programming languages on our metric.
Capability systems. The object-capability model originates with Dennis and Van Horn (Dennis and Van Horn 1966). CHERI (Watson et al. 2015) implements hardware-level capabilities. Zanzibar (Pang et al. 2019) provides scalable relation-based authorization. UCAN (Zelenka et al. 2022) provides decentralized capability delegation. Macaroons (Birgisson et al. 2014) provide contextual caveat-based attenuation. Biscuit (Couprie et al. 2021) combines Macaroons-style attenuation with Datalog-based authorization logic. Our contribution is identifying eight irreducible primitives that span these systems and showing that each system covers a different subset, and noting that the Subject/Authority/Attenuation decomposition was independently arrived at by the protocol spec under operational refinement (§5.2).
Authorization models. RBAC (role-based access control), ABAC (attribute-based access control), and ReBAC (relationship-based access control) represent successive generalizations of authorization. The eight capability primitives map to ABAC’s attribute categories with finer granularity: ABAC’s Action attributes map to Mechanism + Verb (distinct pair-coverages), ABAC’s Environment attributes map to Context, ABAC’s policy attributes map to Authority + Attenuation. Lifecycle management (often outside ABAC’s frame) maps to Revocation.
Content-addressed systems. Git (Torvalds 2005), IPFS (Benet 2014), and Nix (Dolstra et al. 2004) occupy specific positions in the entity substrate primitive space (see The Entity System). Their type system limitations correspond to their positions in the type primitive space: Git’s four hardcoded object types cover Shape partially but lack Composition, Equivalence-for-types, Representation independence, and Evolution.
Schema systems. Avro, Protobuf (Varda 2013), CDDL (Bormann and Hoffman 2020), Cap’n Proto, and ASN.1 are the entity type system’s closest relatives. The convergence of these independently designed systems on the same structural vocabulary is evidence that the vocabulary is forced by the domain.
8. Conclusion
We have described a design validation procedure — declare the design space, survey the landscape, extract irreducible primitives with partial levels, categorize gaps, and map results back to substrate primitives via pair-coverage — and applied it to two design spaces within the entity core protocol.
In type description, eight irreducible primitives emerge from analysis of 16 independent type systems. The entity type system covers all eight at high partial levels. Gaps across all 16 systems fall into three categories (type computation, encoding-specific, domain-specific), each excluded by design with a designated mechanism. The convergence of 14 of 16 systems on the same structural vocabulary is evidence that the vocabulary is forced by the domain rather than chosen by convention.
In authorization, eight irreducible primitives emerge from analysis of capability and access control systems. The entity system covers all eight at high partial levels — the highest of any surveyed system in five-of-eight primitives, tied for highest in two more. Comparison to Zanzibar, UCAN, Macaroons, Biscuit, and CHERI shows that each covers a different subset; none covers all eight. The protocol spec’s §5.2 three-slot model, developed operationally to fix cross-peer capability bugs, independently arrives at the same Subject/Authority/Attenuation decomposition the methodology produces by structural test — a convergence between operational refinement and theoretical decomposition that strengthens both.
The cross-compilation partition provides a third independent validation: the same A/B/C split across five languages with radically different type systems suggests the entity type system captures a natural abstraction level.
All three analyses — type primitives, capability primitives, cross-compilation partition — were conducted independently of each other and independently of the substrate primitive analysis. That the type primitives ground in E+I+T, the capability primitives ground in the full set, and together the 16 surface primitives require all six substrate primitives is convergent evidence that the protocol’s design choices cover the relevant design spaces.
Open questions:
- Can the irreducibility of either set of eight primitives be formally proved?
- Are there design spaces within the entity system beyond type description and authorization that warrant primitive analysis (e.g., subscription, query, revision)?
- Can the procedure be applied to other protocols to identify primitive gaps before release?
- Is the coincidence of both analyses finding exactly eight primitives structurally significant, or is it coincidence?
- The convergence of methodology and spec on the three-slot (Sb/Au/At) decomposition is the load-bearing example; are there other places where the methodology and spec routes would be expected to converge and have not yet been checked?
9. Appendix: History and Methodology Reconciliation
This appendix records the reconciliation between this paper’s original framing (seven dimensions per design space) and the formal structural methodology of A Structural Methodology for Information System Domains (which surfaces eight primitives per design space). It is included for transparency about the paper’s evolution and as a worked example of methodology-applied-back to validate pre-methodology analytical work.
9.1. How this paper began
The first version of this paper was authored before the structural methodology of A Structural Methodology for Information System Domains had crystallized. The intuition was already operative — survey the landscape, find the irreducible axes, validate against the entity primitives — but the formal procedure was not. Steps that the mature methodology requires explicitly (domain-type declaration; partial-level decomposition; dependency graph among primitives; Hasse lattice; build-up sequence; load-bearing composition identification; emergent-property prediction map; cross-domain structural pattern observation) were either absent or implicit. The paper used “dimensions” rather than “primitives” — a choice that turned out to elide the distinction between Layer 1 (primitives) and Layer 4 (emergent surface properties) in the four-layer framework.
The paper produced two findings nonetheless: seven type description dimensions and seven authorization dimensions, with both grounded in entity-substrate pair-coverage. These findings were substantially correct — the seven dimensions in each design space all correspond to real structural axes — but the formal methodology, applied back to the same two design spaces, surfaced refinements:
9.2. Type-system reconciliation
The methodology applied to type-systems-as-a-domain produces eight primitives: Naming, Shape, Cardinality, Constraint, Composition, Equivalence, Representation, Evolution. The original seven dimensions map as follows:
| Original dimension | Methodology primitive | Note |
|---|---|---|
| Shape | Shape | Same |
| Constraint | Constraint | Same |
| Optionality | Cardinality | Renamed and broadened; cardinality covers optional + repeated + uniqueness |
| Composition | Composition | Same |
| Identity | Equivalence (Eq3 partial level) | “Identity” is the content-derived partial level of the broader Equivalence primitive |
| Encoding | Representation | Renamed; Encoding is one mechanism by which Representation operates |
| Evolution | Evolution | Same |
| (not in original) | Naming | Methodology surfaces Naming as separable; the original took it for granted because every surveyed system has it |
The substrate-grounding finding (all type primitives ground in the EIT triangle) is preserved exactly: Naming grounds in ET, the other seven ground as in the original. The refinement is more accurate vocabulary, not a structural revision.
9.3. Capability-system reconciliation
The methodology applied to capability-systems-as-a-domain produces eight primitives: Subject, Mechanism, Verb, Object, Context, Authority, Attenuation, Revocation. The original seven dimensions map as follows:
| Original dimension | Methodology primitive | Note |
|---|---|---|
| Subject | Subject | Same vocabulary, narrower semantic scope (no longer includes Authority) |
| Handler | Mechanism | Renamed |
| Operation | Verb | Renamed |
| Resource | Object | Renamed |
| Peer | Context (partial level: spatial axis) | Merged into Context as one of its partial-level axes |
| Time | Context (partial level: temporal axis) | Merged into Context as one of its partial-level axes |
| Delegation | Attenuation (with Authority as separate primitive) | The original “Delegation” decomposes into the {Au, At} pair-relationship; the methodology promotes Authority to a separate primitive |
| (not in original) | Authority | Methodology surfaces this; spec §5.2 independently surfaced it operationally |
| (not in original) | Revocation | Methodology surfaces this; the spec’s “Revocation model” + EXTENSION-ROLE 401 status independently has it |
The Context merge (Peer + Time → Context) is a methodology choice with a defensible alternative — splitting them back out, as the original did, is also reasonable for distributed systems. Both decompositions agree on the substrate pair-coverage requirements; the disagreement is at the surface-primitive level only.
The Authority and Revocation additions are the substantive refinements. Both are present in the spec and in the cap-systems literature, and both were missed in the original analysis. The reconciliation surfaces them, the comparison table now scores systems on both, and the entity system’s reach across all eight primitives is recorded.
9.4. What the reconciliation does not change
- The grounding of all surface primitives in substrate primitives via pair-coverage.
- The use of EIT, TMX, and IXP as the named structural triangles that surface primitives activate.
- The phase-transition pairs (IX, IP) requiring Full I for capability completeness.
- The cross-compilation partition.
- The “schema systems concentrate in EIT triangle” observation.
- The 4+4 architecture of the capability grant (the four per-grant primitives + four per-token/lifecycle primitives).
9.5. How the methodology was applied back
The methodology canonical analyses for type systems and capability systems are under the project’s methodology directory (methodology/type_systems_domain_analysis/ and methodology/capability_systems_domain_analysis/). They follow the 12-step procedure of A Structural Methodology for Information System Domains §2.1: information gathering, landscape analysis, primitive extraction with partial-level iteration, dependency specification, pair enumeration and load classification, coherent sub-lattice construction, build-up sequences, load-bearing composition identification, emergent-property prediction, cross-domain pattern observation, literature alignment.
The methodology-applied-back exercise is itself an example of methodology-on-methodology: applying the structural procedure to pre-methodology empirical work to test whether the empirical analysis would survive formalization. In this case, it largely did. The refinements are sharpening, not overturning. This is the kind of cross-validation that gives the methodology its claim to general applicability: the same procedure that surfaced primitives across roughly twenty other domains (see A Structural Methodology for Information System Domains) also reproduces and refines the pre-methodology findings of this paper.
9.6. Why this matters beyond this paper
Two practical consequences:
The protocol spec is already where the methodology says it should be. Authority is §5.2’s “root” / chain root slot. Revocation is the spec’s “Revocation model” section and the
system/capability/revocationentity type. Naming is thesystem/type/Xpath convention. No spec amendments are implied by the methodology refinements above. The discrepancy was entirely between this paper and reality; the spec and reality agreed.The convergence of operational refinement (the spec’s §5.2) with theoretical decomposition (methodology) is itself a finding. It suggests that the substrate primitive set is structurally complete for these design spaces in a sense neither route could have established alone. Two independent routes arriving at the same three-slot decomposition is the kind of evidence the paper’s whole design-validation thesis is about. The third route (cross-compilation partition) gives a fourth piece of consistent evidence within the type-system half of the analysis.
Entity System Security Architecture: Capabilities, Identity, and Trust in Content-Addressed Typed Data
We describe the security architecture of the entity system, in which every security mechanism is constructed from the same six primitives — Entity, Identity, Tree, Emit, Execution, and Peer — that define the system itself. Authorization uses four-dimensional capability grants (handler, operation, resource, peer) with cryptographic attenuation: each capability token is an entity, content-addressed, signed, and verifiable independently of any session. Identity is content-derived: peer IDs are hashes of public keys, and identity records compose into mini-trees that travel with the peer. Revocation uses the tree’s mutable layer (unbind = revoke; verify = check the root is still bound), eliminating blacklists at the substrate level and supporting O(1) scoped mass revocation through generation pools. Encryption is entity-level — the same encrypted entity on wire, disk, and in memory — with self, peer, and group modes, and is scoped to stateless single-shot use: interactive session encryption is structurally separate work, and we mark where the modes on offer stop, including the absence of forward secrecy against a compromised recipient. The security model rests structurally on the IXP capability triangle: a capability’s meaning depends on content-addressed identity (IX), cross-peer dispatch (XP), and content-addressed peer identity (IP) acting together. Two of these pairs (IX, IP) are phase-transition pairs: they require Full I — content-derived identity — to activate at all. A system at assigned identity cannot host this capability model in the entity-system sense, regardless of how many fields its grants have. We compare to Macaroons, UCAN, Biscuit, and Zanzibar, position the entity system in the broader landscape of high-primitive systems analyzed in Convergent Evolution, and contrast the “trust the identity” stance with the “trust the code” stance of Holochain and the steward-trust models of Plan 9 and Inferno. The architecture has been under continuous reduction throughout the protocol’s evolution; the security model has not required wire-format change.
1. Introduction
Security in distributed systems is usually bolted on. Identity, authorization, audit, revocation, and confidentiality each get their own subsystem, their own data model, their own deployment story. The integration between them — expressed in TLS configurations, IAM policies, session cookies, audit logs, certificate revocation lists, and out-of-band key exchanges — accumulates as accidental complexity.
The entity system is built differently. The same six primitives that define the system (see The Entity System) also carry every security mechanism. Capability tokens are entities. Peer identities are entities. Delegation chains are content-addressed. Revocation uses the tree’s mutable binding layer. Encryption wraps entities and preserves their identity. There is no separate “security layer” because there is no separate substance: typed content-addressed data is the substrate for data and for security alike.
This paper is the dedicated treatment of how that security model works end-to-end. The Entity Core Protocol covers the security mechanisms in protocol context — wire format, message structure, capability-token layout, the connection handshake. This paper goes deeper: how the mechanisms compose, how they are deployed, what they imply about peer roles and trust boundaries, and where they sit in the broader landscape of capability-based and access-control systems.
1.1. What Lives Where
Security in the entity system lives at the IXP capability triangle (see The Entity System) — one of the five named structural triangles formed by the six primitives. The triangle’s three pairs each carry part of the substrate:
- IX (Identity × Execution): the capability-as-content-addressed-entity. A capability token is an entity, its identity is its content hash, and verification across implementations converges by hash equality.
- XP (Execution × Peer): cross-peer dispatch carrying capabilities. Every
EXECUTEbetween peers carries its own capability token; authorization is per-message, not per-session. - IP (Identity × Peer): content-addressed peer identity. A peer’s ID is a hash of its public key. Same key, same ID, everywhere, always.
Two of these pairs are phase-transition pairs in the sense developed in The Entity System: IX (capability convergence verification) and IP (peer-ID derivation) do not activate at partial Identity levels. A system at I1 (assigned identity, not content-derived) cannot host the entity system’s capability model regardless of how richly its grant structure is specified. This is the structural reason content-derived identity is a precondition for the security model, not a complement to it. Without Full I, the IXP triangle has at most one pair active (XP), and the capability mechanism degrades to a session-bound authorization model.
Security mechanisms outside the IXP triangle ground in other structural locations:
- Authorization at the dispatch boundary uses the TX pair (handler dispatch via tree-walk) and the EX pair (typed handler operations). The four-dimensional grant covers exactly these: handler (TX), operation (EX), resource (TP for peer-namespaced paths), and peer (XP).
- Audit uses the ITM emit triangle (see The Entity System). Content storage is append-only along the IM axis (Store is monotone over content); the binding layer at TM carries revocation as ordinary binding changes. The IM/TM split is what lets audit and revocation compose without conflict: they live on different axes of the same primitive.
- Confidentiality lives at the EI pair: encrypted entities are typed and content-addressed exactly like any other entity. Authorization (IXP) and confidentiality (EI) are independent dimensions; either can apply without the other, and together they give defense in depth.
The capability model is the only authorization mechanism in the entity system. There is no parallel ACL system, no role table, no session cookie. Roles are expressed as capability-issuing patterns; groups are membership records that produce capabilities; clusters are mutual-trust patterns that share generation pools. The same mechanism handles every authorization question because the substrate provides only one.
1.2. What This Paper Covers
The paper is organized around five questions:
- Who is acting? The identity model: content-addressed peer IDs, algorithm agility, identity entities as mini-trees, the connection handshake, peer roles.
- What may they do? The capability architecture: four-dimensional grants, attenuation by construction, delegation chains, two-level verification, handler authority.
- What happens when they should no longer act? Revocation: tree-based unbinding, generation pools, TTL, and the tiered implementation that scales from minimal deployments to large clusters.
- What may they understand? Encryption: entity-level encryption with self, peer, and group modes. Scoped to stateless single-shot use — interactive session encryption is separate work and is not covered here — and specified but not yet exercised in deployment.
- How is this used in practice? Deployment patterns: peer-role configurations, delegation patterns, cluster and group patterns, information disclosure control, incident response.
A comparative analysis section positions the entity system against existing capability systems (Macaroons, UCAN, Biscuit, Zanzibar) and against the security philosophies of high-primitive systems (Holochain’s “trust the code”, Plan 9’s “trust the steward”). The analysis grounds in the landscape developed in Convergent Evolution: of the systems analyzed there, the entity system is the only one that activates the full IXP triangle simultaneously.
1.3. What This Paper Does Not Cover
The six primitives and their build-up sequence are in The Entity System. Wire format, message layout, and the bootstrap handler manifest are in The Entity Core Protocol. Computational architecture and self-description are in The Entity Church Architecture. The full landscape analysis with cross-system scoring is in Convergent Evolution. OS-level deployment patterns and security tiers belong to DEOS; application-level security guidance belongs to Application Architecture. We assume familiarity with the primitives and pair-relationship framework from The Entity System; specific pair and triangle names (IXP, EIT, ITM, TMX, TXP) are used without re-introducing them.
2. Identity
Authorization rests on identity, but in this system “identity” is not one thing. It is a small stack of structurally distinct mechanisms composed under a discipline. At the bottom sits a cryptographic peer ID — the per-keypair identity that lets a peer sign and be recognised. Above that sits an optional identity layer that maintains a peer graph of attestations over time, supports recovery from key loss or compromise, and exposes a stable handle to contacts even as the underlying keys rotate. This section describes both: the peer-keypair foundation, the four-extension identity stack on top, the standard setup users should default to, and the recovery model that makes the whole thing survivable.
2.1. Peer IDs and the Peer Keypair Entity
The lowest layer of identity is per-keypair. Each peer has an Ed25519 keypair; the peer’s identifier is derived deterministically from the public key:
Three single-byte format codes pin the cryptographic choices:
key_type: which signature algorithm the public key uses (currently Ed25519, code0x00).hash_type: which hash algorithm derives the ID from the key (currently SHA-256, code0x00).- A separate format code on every content hash pins the content-addressing algorithm (also
0x00for ECFv1-SHA-256 today).
The three namespaces are independent: a deployment can adopt a new content-hash algorithm without changing peer IDs, a new peer-ID hash without changing keys, and a new signature scheme without changing existing hashes. Algorithm agility is built into the format, not bolted onto a separate negotiation layer.
The resulting peer ID is 46 characters of Base58. Collision analysis under generous assumptions ( peers, connection events per peer per year) yields a per-event collision probability around , which is structurally adequate: a collision would not produce a security failure but would produce a routing confusion that any two affected peers could detect by comparing keys.
The peer’s keypair is itself an entity — the peer keypair entity at system/peer — holding the public key, key-type, and a self-signature. Every peer has one; it is the substrate every other identity mechanism builds on. An earlier revision named this entity system/identity; it was renamed to system/peer to avoid colliding with the identity-extension layer above.
A peer keypair is not yet a user identity. A single-user, single-device deployment can use the peer keypair as their identity (and we describe this as the core-only configuration below). For anything beyond that — multi-device, recovery from key loss, stable handles that survive key rotation — the identity extension layers on top.
2.2. Three Structurally Distinct Validation Classes
Before we describe the identity layer, the security architecture rests on an invariant that constrains its shape: there are three parallel classes of signed entity in the system, and they share no validator.
- Core capability tokens — chain-walked by the core protocol’s
verify_capability_chain, which checks the parent-reference chain, signature at each link, attenuation on every grant dimension, and freshness. Capabilities are how peers authorise specific actions. system/attestationentities — signed claims that one peer makes about another, with kind-discriminated semantics. Validated byEXTENSION-ATTESTATIONhelpers plus consumer-specific predicates. Attestations are how peers certify state without thereby authorising operations.system/quorumentities — K-of-N signer sets, validated byEXTENSION-QUORUM’sverify_k_of_n_signatures. Quorums are how a collective decision is expressed as a single verifiable entity.
These are three distinct entity types validated by three distinct functions and dispatched along three distinct paths. No code path treats a capability token, an attestation, and a quorum entity as interchangeable signed objects. This is a security invariant, not a stylistic choice. The natural implementation mistake — reusing the capability-chain walker for “anything multi-signed” — would collapse the security model: a multi-sig capability could be confused with a quorum decision; a controller certificate could be confused with a delegated authorisation. The architecture forbids this and the conformance tests check that implementations honour the separation.
The identity layer above composes these three classes into deployment-ready identity machinery; the separation gates the composition rather than constraining it.
2.3. The Identity Stack
Four extensions, in two layers, comprise the identity machinery:
| Extension | Layer | Provides |
|---|---|---|
EXTENSION-ATTESTATION |
Substrate | The system/attestation entity type; signature validation; supersedes chains; liveness checks (not_before, expires_at, transitive supersession, self-revocation). |
EXTENSION-QUORUM |
Substrate | The system/quorum entity type; K-of-N validation; pluggable signer-resolution (concrete-peer / identity-resolved); quorum lifecycle events (quorum-update, quorum-publish). |
EXTENSION-IDENTITY |
Composition | The cert-chain framework: identity-cert attestations, four standard functions (controller, agent, identifier, app-defined), peer-config per agent, rotation kinds, contact-side caching, recovery flow. |
EXTENSION-ROLE |
Composition | RBAC over identity: role definitions, role-derived capabilities, three-layer exclusion, delegation. |
The two substrate extensions are kind-agnostic by design: their primitives are reusable by any future consumer (group, transaction, governance, verifiable credentials, reputation, provenance, audit). The two composition extensions encode identity-specific and role-specific semantics on top.
Three of the four are specified and implemented; the role extension is the one still settling, and we mark where the paper leans on it. We name no version numbers: extension versions move independently of this paper, and a reader who needs the current revision of any of them should read the extension specification rather than trust a number printed here.
Implementations may opt out of the identity layer entirely (the core-only configuration described below); when an implementation installs IDENTITY it MUST also implement ATTESTATION and QUORUM, because IDENTITY’s mechanics actively compose them (registering an identity-resolved resolver against QUORUM at install time, wrapping ATTESTATION’s create/supersede/revoke ops with identity-specific properties and path conventions, dispatching side effects on attestation arrival via a process_attestation sync hook).
2.4. The Cert-Chain Framework
Identity, as the extension models it, is a peer graph rooted at a quorum. A K-of-N quorum sits at the structural root; certs are directed edges; functions (controller, agent, identifier, app-defined) are graph positions established by certs rather than properties stored on peers.
The model has four characteristic features:
Quorum-rooted. Every cert chain terminates at a top-level cert whose attesting field references the quorum’s identifier. The quorum is the trust anchor; verifiers walking any cert chain back to the quorum can validate the chain end-to-end against the K-of-N requirement.
Four standard functions. A cert’s properties.function field names a structural position:
- controller — authority to delegate within the identity (sign agent certs, write internal-management entities, issue local-peer capabilities to the controller’s keypair).
- agent — authority to act on behalf of the identity from a specific device. One agent per device daemon, typically; agent certs are signed by the controller (in the three-key default) or by the identifier (in the four-key advanced shape).
- identifier (four-key only) — the cert function contacts cache as the identity’s handle. Distinct from controller so that controllers can rotate without contacts re-validating.
- app-defined — consumers can register additional function values for domain-specific authority (audit-log signer, service account, custodial agent, etc.).
Chain depth bounded but flexible. Sub-controller chains allow a controller to issue a subordinate controller cert; the chain MUST terminate at a top-level controller (attesting = quorum_id). Default maximum chain depth is 32 per the substrate’s walk_attesting_chain parameter; identity sub-controller chains are typically shallow (2–3 levels).
Functions emerge from graph position, not from peer-side state. A peer is a controller because a cert with function="controller" chains it back to a quorum; revoking that cert (via supersedes, retirement, or revocation) removes the function. The peer’s keypair is unchanged; what changes is its position in the identity graph. This makes role transitions a graph operation, not a state migration.
The four identity-context attestation kinds (registered under the substrate’s kind-ownership table, namespace-prefixed with identity-) carry the lifecycle:
"identity-cert"— active certification of a peer for a function."identity-rotation-handoff"— graceful key roll; dual-signed by old and new key."identity-rotation-recovery"— compromise-recovery; K-of-N signed by the quorum."identity-retirement"— explicit cert retirement; K-of-N signed.
The substrate’s universal "revocation" kind applies on top of these, with identity’s own authority rules over who may revoke what (per identity_is_authorized_revoker).
2.5. Configuration Progression
The identity extension is opt-in, and not every deployment needs the full machinery. Configurations form a progression from cryptographically minimal (per-keypair only) through the recommended default (three-key with recovery) to advanced shapes:
Core-only
The identity extension is not installed. Each peer’s identity IS its keypair; the peer ID derived from the public key is the identity handle. Single-device, single-key, no recovery, no rotation. Loss of the key is loss of the identity; cross-peer recognition is by raw peer ID. Valid for closed networks, dev environments, IoT devices not intended to survive replacement.
1-of-1 quorum
The identity extension is installed but the quorum has one constituent with threshold 1. The cert-chain machinery operates correctly — agent certs sign other entities, rotation events compose — but no recovery is possible (loss of the single quorum constituent is catastrophic). Useful when a deployment wants the architectural shape (rotation, agent abstraction, controller-mediated grants) but accepts no recovery property.
Three-key default (recommended)
The canonical setup. Three peer functions:
- Quorum constituents. N peers, K-of-N threshold (typically K = 2, N = 3 or 5). Constituent keys held in cold custody: paper backup, hardware token, secondary device, or trusted holder. Used rarely — only for recovery, quorum updates, and minting new top-level controller certs.
- Controller. Hot, encrypted at rest. Signs internal-management entities: peer-config writes, role-assignment records, agent certs. In the three-key default the controller’s key IS the identifier — contacts cache the controller’s public key as the identity’s handle.
- Agents. One per device daemon, hot, on each running device. Sign cross-peer capability tokens (core-standard, per The Entity Core Protocol). The controller authorises each agent via an agent cert.
This configuration delivers the three properties most users actually want: recovery (K-of-N quorum can recover from controller compromise), multi-device (each device runs its own agent with its own keypair, all under the same controller), and stable cross-peer recognition (contacts cache the controller’s key; the identity survives device additions and replacements).
The setup ceremony is documented in §6 of EXTENSION-IDENTITY and is exposed via the system/identity:configure handler. In outline:
- Choose N quorum constituents and the threshold K. Distribute the constituent keys across diverse custody (geographic, custodial, hardware-class) so that an attacker cannot reach K of them simultaneously without an extraordinary effort.
- Mint the initial quorum entity (
system/quorum:create) and seed it with the N constituent public keys plus the threshold. - K of the constituents sign the controller cert (kind =
identity-cert, function =controller, attesting = quorum). The cert lives atsystem/identity/public/cert/{cert_hash_hex}and is published as part of the contact-facing sync surface. - The controller mints agent certs for each device (kind =
identity-cert, function =agent, attesting = controller’s key). Initially each agent cert lives in mode =internal(privacy default); contacts who need to recognise the agent receive published versions (mode =publicor mode =relationships/{contact_id}) per the deployment’s contact policy. - Each agent runs
system/identity:configureto bind its local peer-config to the trusted quorum, validate the live controller cert chain, and mint the local-peer-to-controller capability that lets subsequent operations dispatch under the controller’s authority.
After this ceremony the identity is operational. Day-to-day work runs through the agents under controller-derived authority. The quorum constituents return to cold custody until rotation, recovery, or membership change.
Four-key advanced
The three-key default conflates the controller (signs internal management) and the identifier (contacts cache as the handle). Some deployments want these separated — controllers should rotate frequently for hygiene, but contacts should not re-validate every rotation. The four-key advanced shape adds an identifier peer:
- The controller rotates frequently; this is invisible to contacts.
- The identifier rotates rarely (only on compromise of the identifier itself). Contacts cache the identifier’s key as the handle.
- Agent certs are signed by the identifier (not the controller), since contacts cache the identifier’s key as the recognition anchor.
Most deployments do not need this. We document it as opt-in; the three-key default carries the load-bearing properties.
Other supported variants
The following composition shapes are normative configurations that compose from the same primitives:
- Multi-binding. A single host machine MAY operate as multiple agents (one per identity it serves) — personal and service-account on the same laptop, for example. Each agent has its own peer-config in its own peer namespace; peer-configs MUST NOT share state across identities.
- Concurrent multi-controller. Multiple controllers live concurrently under the same quorum (desktop + phone deployments where each device holds its own controller). Each agent holds one local-peer-to-controller capability per live controller.
- Sub-controller chains. A controller cert can be issued by another controller (rather than directly by the quorum), enabling delegated management hierarchies. The chain MUST terminate at a top-level controller whose
attesting = quorum_id. - App-defined functions. Custom function values (e.g.,
function="audit-log-signer",function="service-account") follow the standard cert lifecycle uniformly. - Parent-managed. Controller keys held initially by a parental peer; the subject acquires their own keys over time via
quorum-updateceremonies that add the subject’s peers to the quorum and eventually remove the parental ones. Used for child-account or device-onboarding scenarios.
The progression composes: a deployment can adopt the three-key default and later add sub-controllers, transition from parent-managed to self-custody, or expand to four-key when contact-stability requirements emerge. Each transition is itself a sequence of standard cert lifecycle events.
2.6. The Recovery Cluster
The quorum at the root of an identity is the recovery mechanism. We describe it as a recovery cluster to emphasise its operational character: it is not a routine signing surface but a small set of cold-stored keys whose collective authority can re-establish the identity if a controller is lost or compromised.
Custodial diversity. The N constituent keys should be held across diverse failure modes:
- Geographic diversity. Constituents in physically separated locations so a single fire, theft, or seizure does not reach K of them.
- Custodial diversity. A mix of self-held (paper backup in a safe, hardware token on a keychain, secondary device in a different location) and trust-held (lawyer, family member, employer). The trust assumption is that at most N − K of them collude or are coerced simultaneously.
- Hardware diversity. Some constituents on hardware tokens (YubiKey-class devices), some on software wallets, some on paper. A single supply-chain compromise does not reach all custody.
The threshold K controls the survivability/safety trade-off: low K (1-of-3) tolerates more loss but accepts lower attacker work; high K (3-of-5) tolerates one or two losses but requires more attackers to collude. The recommended default for personal identities is K = 2, N = 3 or K = 3, N = 5; institutional identities often use higher thresholds.
Recovery flow. When a controller is compromised or its key is lost, recovery proceeds as follows:
- The user assembles K constituent signatures (K-of-N) on an
identity-rotation-recoveryattestation. This is a coordinated event: the constituents need to be reachable, but the K-of-N signature gathering can be asynchronous (via the proposals subtree convention in §8 ofEXTENSION-IDENTITY). - The recovery attestation references the prior controller cert (in
properties.target_cert) and asserts a new controller cert (in the same supersedes chain) issued to a fresh controller keypair. - Contacts processing the recovery attestation validate the K-of-N signatures against their cached
quorum-publishattestation for the identity — the prior signer set that the contact already trusts. If the K-of-N signatures verify against that cached state, the contact accepts the new controller and updates its handle cache to the new key. - Contacts that never received a
quorum-publishfor this identity MUST reject the recovery (fail-closed). Deployments opting out ofquorum-publishpublication accept that compromise-recovery falls back to out-of-band re-establishment: the user sends contacts a fresh signed introduction, and contacts trust-on-first-use the new identity.
The fail-closed property is load-bearing for the security model. Without it, an attacker holding arbitrary signatures could synthesise a “recovery” event and convince contacts to update their address books. The cached quorum-publish is the contact’s trust anchor; recoveries that cannot validate against it are not honoured.
Quorum compromise. If more than N − K of the quorum’s constituent keys are compromised simultaneously, the attacker can sign any quorum-authorised attestation and the identity is fully compromised. The architecture mitigates this through K, N, and custodial diversity, but cannot eliminate it. Quorum compromise is the worst-case failure mode of any K-of-N system; the parameters are deployment choices reflecting the deployment’s threat model.
2.7. Rotation Mechanics
Three kinds of rotation appear in the cert lifecycle, each with distinct signing requirements and use cases:
identity-rotation-handoff(graceful, dual-signed). Routine key roll: the old key signs and the new key signs the same attestation, demonstrating that the rotation is consensual. Used for hygiene rotation, scheduled key replacement, and planned device replacement. The dual signature is the security property — an attacker holding only the old key cannot complete the handoff alone; an attacker holding only the new key cannot either.identity-rotation-recovery(compromise, K-of-N quorum signed). Described above. Used when the old key is unavailable (lost, compromised, or destroyed). The quorum is the only signing path that does not require possession of the old key.identity-retirement(explicit termination, K-of-N quorum signed). Marks a cert as terminally retired (no successor); the chain dead-ends. Used when an identity is decommissioned (former employee, retired service account) or when a delegated sub-controller is removed without replacement.
Identity-rotation-handoff and identity-rotation-recovery preserve the identity (the handle the contacts cache); they replace the key behind the handle. The contact-side caching layer (§5.1 in EXTENSION-IDENTITY) tracks the supersedes chain and updates the handle cache to the current live key as rotations arrive. Identity-retirement terminates the chain; subsequent attestations attempting to reference the retired cert do not chain-validate.
2.8. Public-Facing Identity
What contacts see depends on which subtree of an identity is exposed to sync. The identity extension defines a small set of audience tiers:
system/identity/internal/...— internal management state. NOT synced to contacts. Includes peer-config, internal-mode agent certs (privacy default), sub-controller certs that are deployment-internal.system/identity/public/...— the public face of the identity. Synced to all contacts. Contains the top-level controller cert (in the three-key default) or identifier cert (in the four-key advanced), plus agent certs in mode =public.system/identity/relationships/{contact_id}/...— per-relationship publication. Synced only to the named contact. Used for agent certs the identity has minted specifically for one contact (mode =per-relationship).system/quorum/{trusts_quorum}/...— the quorum’s published state, includingquorum-publishevents that contacts cache as the recovery trust anchor. Synced to all contacts as part of the identity’s dual-subtree sync surface.
Dual-subtree sync. Contacts receive both system/identity/public/... AND system/quorum/{trusts_quorum}/... as a unit. The quorum state is necessary for recovery validation; the public certs are necessary for connection authentication. Either alone is insufficient.
Operational-key confinement (MUST). Controller signatures NEVER appear under system/identity/public/.... This is a structural invariant: implementations MUST reject attestations under public paths carrying signatures from any currently-live controller of the trusted quorum. The invariant prevents an attacker who has compromised a controller from publishing controller-signed attestations to public paths and tricking contacts into trusting them. Controllers sign internal-management entities only; the K-of-N quorum signs everything that crosses to the public surface.
Privacy opt-out. Deployments may decline to publish quorum-publish. The trade-off is recovery ergonomics: contacts cannot validate identity-rotation-recovery events without a cached quorum-publish, so compromise-recovery degrades to out-of-band re-establishment. The architecture honours both choices: high-privacy deployments accept the out-of-band recovery flow; high-availability deployments publish quorum-publish so recovery is automatic.
2.9. Connection Establishment
The three-message connection handshake (see The Entity Core Protocol) is structured as three EXECUTE round-trips:
- HELLO. Initiator presents its peer keypair entity, protocol version, and supported algorithm sets. Responder presents the same. The intersection of algorithm sets becomes the negotiated set for this connection.
- AUTHENTICATE. A nonce-based proof of possession: each peer signs a challenge produced by the other. The signature is verifiable against the public key referenced in the peer keypair entity. Mutual authentication completes here.
- Initial capability grant. The responder issues the initiator a starting capability covering what the initiator may immediately do — typically read access to the responder’s handler manifest plus the ability to request additional capabilities.
For peers running the identity extension, the HELLO carries the peer’s agent cert (and the cert chain back to the quorum) alongside the peer keypair entity. The responder validates the agent cert chain against the trusted quorum’s cached quorum-publish and (if accepted) issues the initial grant under authority derived from the identity context. For core-only peers, the HELLO carries only the peer keypair entity and the responder authenticates against the raw peer ID.
The handshake uses the same EXECUTE dispatch as everything else; there is no special connection protocol. Pre-authentication, only the connection handler at system/protocol/connect is reachable; post-authentication, the initial grant determines reachability.
2.10. Peer Roles in Deployment
In deployment, peers occupy a small number of structural roles, each with a characteristic capability and tree configuration. These are patterns the system supports rather than enumerated types; deployments compose them as needed.
- Long-lived peers. Stable identity (durable controller-cert chain in a three-key or four-key setup), persistent tree, full capability model. The typical user-facing peer.
- Service peers. Handler-focused. Limited tree (just the handler manifest, configuration, and operational state), grant-scoped to the operations they implement. Identity-wise, often a service-account identity with its own quorum.
- Relay peers. Route messages between peers without reading content. Capabilities cover routing operations (forwarding, queueing); encrypted content remains opaque to them. May run as a core-only peer if no identity-layer features are required.
- Light peers. Minimal tree, request-only, no handler hosting. Mobile clients, IoT devices, ephemeral session participants. Typically agents of a heavier identity (the user’s main identity) rather than identities of their own.
- Cluster peers. A set of peers with mutual full trust within an infrastructure boundary, sharing generation pools. Note: cluster in this sense refers to the planned
system/clusterruntime-coordination layer (HA, replication, leader election), distinct from group, which is the identity-level concept for multi-user collective identities (perEXTENSION-GROUP). Cluster peers are an infrastructure pattern; group identities are an identity-extension consumer.
Each role is a configuration of identity, capability, tree, and (when applicable) encryption. The roles do not need separate spec support: they emerge from how the primitives are deployed.
2.11. Key Hierarchy
Three classes of keys appear at distinct lifetimes:
- Identity keys. Long-lived. Ed25519 keypairs whose public key derives the peer ID. Quorum constituent keys, controller keys, identifier keys (four-key only), and agent keys all sit here. Rotated under controller authority (handoff) or quorum authority (recovery) through the identity extension.
- Encryption subkeys. Long-lived but separately rotatable. X25519 keypairs derived from, or attested by, identity keys. Used for key agreement when establishing per-entity encryption keys. Separating signing and encryption follows standard cryptographic practice: an identity-key compromise does not immediately decrypt past traffic if the encryption subkey is rotated independently.
- Ephemeral keys. Short-lived. Per-entity or per-session symmetric keys, derived from key agreement, discarded after use. Forward secrecy lives here: a compromise of long-lived keys does not retroactively decrypt past sessions, because the ephemeral keys are no longer available.
The key hierarchy is enforced through the extension layer (identity for the long-lived part, the encryption extension for the ephemeral part). The substrate is agnostic: any peer that signs entities, derives content hashes, and verifies signatures has the cryptographic primitives the substrate requires.
3. Capability Architecture
The capability system is the core authorization mechanism. Every EXECUTE carries its own capability token; verification is per-message and stateless. We describe the structure of a capability, how attenuation is enforced, how delegation chains are verified, and how the two-level dispatch check works.
3.1. Four-Dimensional Grants
A capability token is an entity:
system/capability := {
granter: bytes, # peer ID hash of the issuing peer
grantee: bytes, # peer ID hash of the receiving peer
parent: hash?, # content hash of parent capability (null for root)
grants: [grant_entry], # what this capability authorizes
caveats: map?, # delegation constraints (depth, TTL, no-delegate)
not_before: timestamp,
expires_at: timestamp,
signature: bytes # signature by granter over the rest
}
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]?
}
The grant entry has one field per per-grant-entry primitive that varies per grant: handler (Mechanism), resource (Object), operation (Verb), peer (Context spatial axis). These four are derived in Dimensional Completeness from analysis of the attribute structure of distributed-system authorization requests. A request to a peer for an operation on a resource via a handler has exactly these four per-grant-entry scopes; four additional per-token primitives (subject, authority, attenuation, and context-temporal) live at the capability-token level above the grant entries, and a separate revocation mechanism operates outside the token via system/capability/revocation.
All four dimensions in a single grant are conjunctive: a request matches the grant only if every one of (handler, resource, operation, peer) falls within its respective scope. Two grants in the same token are alternative: a request is authorized if it matches any of the token’s grant entries. This gives capability tokens compositional structure: a single token can authorize different things on different paths to different peers, without forcing a one-grant-per-target inflation.
The scope structure (include plus optional exclude) supports the same patterns across all four dimensions: exact matches, prefix patterns, wildcards. Pattern matching is uniform: the same matching algorithm applies to a handler scope as to a resource scope as to a peer scope. This uniformity is what makes the four-dimensional grant tractable: a verifier has one matching primitive, applied four times per check, rather than four different match logics.
3.2. Attenuation by Construction
A child capability must be a subset of its parent on every one of the four grant dimensions. Verification enforces this:
- For each grant entry in the child, there exists a grant entry in the parent such that every dimension of the child’s entry is a subset of the corresponding dimension of the parent’s.
- Subset is structural: every pattern in the child’s include must be covered by the parent’s include and not excluded; the child’s exclude can be larger than the parent’s.
- Caveats can only narrow: a child can shorten the not-before / expires-at window, lower the max-delegation-depth, or add a no-delegation caveat, but cannot expand any of these.
The verification is mechanical. Given a child and its parent, walking the four-dimensional containment check is bounded by the number of patterns in the scopes (typically small) and produces a single accept/reject. There is no semantic interpretation: subset is set containment, not policy interpretation.
The cryptographic enforcement is the parent-reference chain. The child capability includes parent: hash(parent_capability), and the parent’s content includes its own parent reference, and so on to a root capability. Any attempt to amplify — to insert a more-permissive intermediate, or to swap in a different parent — changes the content hash of the modified link, which breaks the chain because subsequent links reference the original hash. The chain cannot be modified without invalidating it. Amplification requires forging the signature of an intermediate granter; the entity model provides no other path.
3.3. Delegation Chains
A capability’s authority traces to a root capability through a chain of intermediate delegations. The root is a capability whose granter is a peer with structural authority over the resources being granted — typically the peer that owns the relevant tree subtree.
A delegation chain is content-addressed end-to-end. Every capability in the chain references its parent by hash; every reference is verifiable; the chain as a whole is verifiable by walking it and checking signatures, attenuation, and freshness at each step. The chain is also transferable: an EXECUTE envelope can carry the full chain in its included map, and the receiving peer can verify the chain without consulting any other peer. This is what self-authentication means for entity-system capabilities: a token plus its chain is, by itself, sufficient to prove authority.
Chains have a maximum depth (recommended default 64, configurable per deployment). Verification walks the chain link by link, so its cost is linear in depth — each link is a signature check. An attacker who could present an unbounded chain could therefore force unbounded verification work, so a conformant peer MUST enforce a finite maximum depth and reject an over-depth chain cleanly, with a chain_depth_exceeded (400) response, while continuing to serve other requests. The status is deliberately a structural error, not an authorization denial: a too-deep chain is something the caller corrects, not a statement that the caller lacks the capability. The bound’s value is a deployment choice, not a protocol constant — the requirement is that some finite bound is enforced; beyond capping verification cost, the bound forces deployments to design their delegation patterns rather than letting chains grow without limit.
A subtle point about chain verification: the chain proves what was granted at issue time, not what remains valid now. To verify a capability currently authorizes a request, the verifier must additionally check:
- Every link’s signature is valid.
- Every child is properly attenuated against its parent.
- Caveats are satisfied (delegation depth, TTL, no-delegation).
- The current time is within the token’s [not_before, expires_at] window.
- The root capability is still bound in the granter’s tree.
The last point is the link to revocation, covered next.
3.4. The Three Slots: Subject, Authority, Attenuation
A capability chain names three structurally distinct identities, and conflating them is the recurring source of cross-peer authorization bugs. They are independent slots:
- Subject — the grantee at the chain’s tip: the peer that authors the
EXECUTE. Verification checks that the requester is this grantee (grantee == EXECUTE author). - Authority — the chain root: the peer with structural authority over the resources, the source from which permission flows.
- Attenuation — the in-chain granters between root and tip, the installer among them: each link may only narrow what it received, never widen it.
In the single-peer case the three collapse onto one identity — a capability a peer issues to itself has the same peer as subject, authority, and sole attenuator — which is why the distinction is invisible locally and easy to miss. Cross-peer dispatch pulls them apart: the resource owner, the requester, and the attenuators become three different peers, and a check that silently treats any two as one is exactly the class of bug the spec kept hitting.
The protocol spec reached this decomposition empirically. Its §5.2 records the three slots as a clarifying note written after a run of cross-peer capability bugs, each one a place where two slots had been conflated — a chain root mistaken for an in-chain granter, a grantee mistaken for the author. The structural methodology of Dimensional Completeness arrives at the same three by irreducibility testing of the authorization attribute space. Both routes converge.
3.5. Two-Level Verification
A capability check happens at two levels in the dispatch path:
- Level 1 (dispatch). Before the handler runs, the dispatch layer checks the capability token against the four grant dimensions: does any grant entry in the token cover this handler, this operation, this resource, this peer? If not, the request is rejected before the handler sees it.
- Level 2 (handler). Inside the handler, before reading specific paths or performing specific operations, the handler re-checks the capability against the actual paths it will touch. The handler has its own grant (issued when it was registered); the effective authority is the intersection of the caller’s capability and the handler’s own grant.
The two levels are defense in depth. Level 1 catches broad violations cheaply (a peer with a read-only grant attempting a write is rejected at dispatch). Level 2 catches specific violations that the dispatch layer cannot anticipate (the handler may compute the specific path from the request and check it; the dispatch layer only sees the request’s declared scope).
Level 2 also handles the handler-on-behalf-of-caller pattern. When a handler issues sub-requests to other handlers (or to other peers), it can do so on its own authority (using the handler’s own grant) or on the caller’s behalf (passing the caller’s capability through). The two-grant intersection ensures that handlers cannot escalate: a handler issued a narrow grant cannot grant its callers broader access than its own, even if a caller’s capability would have allowed it.
3.6. Handler Authority
A handler’s grant is itself a capability token, issued when the handler is registered and stored at a known path under the handler manifest. The grant defines what the handler is permitted to do — which sub-handlers it may call, which paths it may write, which peers it may contact. Handler registration is an EXECUTE to the system handler at system/handler, and the registering peer’s capability must cover the registration scope: this prevents arbitrary peers from registering handlers with arbitrary grants.
The result is that handler authority is itself capability-scoped. A handler that promises to operate only within a subtree is structurally limited to that subtree by its own grant; if it attempts to act outside, its own capability check fails. The discipline forces handlers to declare their authority surface up front, and the system enforces the declaration.
4. Revocation
A capability that cannot be revoked is, in practice, a capability that lasts forever. TTL bounds are a partial answer; explicit revocation is the complete one. The entity system handles revocation as a tree operation: revoking a capability is unbinding it.
4.1. The Mechanism
A root capability is stored at a known path in the granter’s tree, typically:
system/capability/active/{root_hash}
The system/capability/active/ subtree is the set of currently-active root capabilities the granter has issued. To revoke a capability, the granter unbinds it:
EXECUTE put system/capability/active/{root_hash} → (binding deleted)
Verification then includes a tree-lookup step: at the end of chain walking, the verifier checks whether the root capability is still bound under system/capability/active/. If the binding is present, the chain is live. If absent, the entire chain rooted there is revoked — and because the chain is content-addressed and ordered, every descendant capability also becomes invalid.
This mechanism eliminates the blacklist problem. A blacklist grows monotonically: every revoked credential remains on the list, and verifiers must check the list on every authorization. The tree-based mechanism uses the same lookup that capability verification already requires (a tree get), with no auxiliary structure that grows over time. Revoked capabilities leave no trace in the active set; their content remains in the content store (audit is preserved by the IM axis of emit), but the tree no longer binds them (revocation is the TM axis).
4.2. The IM / TM Split
The two-axis structure of emit (see The Entity System) is what makes audit and revocation compose. Every emit is a Store event (the IM axis: a new content hash enters the immutable content store) and a Bind event (the TM axis: a path’s binding is updated).
- Audit lives on the IM axis. The content store is append-only: every capability ever issued, every entity ever stored, remains addressable by its content hash. A revoked capability is still inspectable; the binding has been removed, but the content endures. Audit logs are queries over the content store, not over the active bindings.
- Revocation lives on the TM axis. The binding at
system/capability/active/{root_hash}is mutable; unbinding it is a TM event. The TM axis is where state changes meaningfully over time; the IM axis preserves history.
Because the two axes are independently observable, an audit consumer can subscribe to IM events (recording every capability issuance) without conflicting with a revocation consumer that subscribes to TM events. The split is structural, not implementational: it follows from how emit is defined as a primitive (see The Entity System).
4.3. Generation Pools
Individual revocation handles individual capabilities. Some deployment scenarios need broader revocation: an employee leaves the company; a relay peer is compromised; a key is rotated. Revoking each affected capability one at a time is slow and error-prone. The generation pool mechanism provides O(1) scoped mass revocation.
A capability can be issued under a pool: a named subtree like system/capability/pool/external_sharing/. The pool itself has a generation counter, stored at system/capability/pool/external_sharing/generation. Capabilities issued under the pool carry a pool_generation field with the value of the counter at issue time.
Verification adds one step: the verifier reads the pool’s current generation and compares it to the capability’s pool_generation. If they match, the capability is current; if they don’t, the capability is revoked. Incrementing the pool’s generation revokes every capability issued under that pool, instantly and in O(1) work: one tree write, with no need to enumerate the affected capabilities.
Pools are independent: revoking the external_sharing pool does not affect the internal pool or the audit pool. Deployments use pools to partition revocation domains: one pool per role, one per cluster, one per project, with revocation of each domain scoped to its pool. The cost of mass revocation becomes constant in the number of affected capabilities, rather than linear.
4.4. TTL as Baseline
Every capability carries not_before and expires_at fields. TTL is the baseline revocation mechanism: a capability with a short TTL is revoked when it expires, with no action required from anyone. Short TTLs (minutes to hours) force frequent refresh and bound the damage window of any single token. Long TTLs (days to weeks) reduce refresh overhead at the cost of slower natural revocation.
TTL handles offline peers without coordination: a peer that cannot reach the granter cannot refresh, and stale capabilities simply expire. The combination of TTL plus explicit revocation gives deployments two knobs: short TTL plus rare explicit revocation, or long TTL plus aggressive explicit revocation, depending on which cost they prefer to pay.
4.5. Tiered Implementation
Real deployments need different levels of revocation infrastructure. The capability specification supports a tiered model:
- Tier 0: TTL only. Capabilities expire; no explicit revocation. Suitable for short-lived sessions and simple deployments.
- Tier 1: + delegation chains with attenuation and caveats (depth, TTL, no-delegation). Still no explicit revocation, but delegation is structured.
- Tier 2: + explicit revocation via the tree-based mechanism. Individual capabilities can be revoked.
- Tier 3: + generation pools, push/pull propagation between peers. Scoped mass revocation, online-optimistic propagation.
- Tier 4: + relationship derivation. Capabilities derived from group membership, role assignment, or other patterns. The most expressive tier; required for large deployments with rich access patterns.
Unknown caveats are rejected (fail-closed). A peer that does not implement a higher tier cannot accidentally accept a capability that relies on a caveat it does not understand: the verifier rejects what it does not know how to check.
4.6. Trade-Offs
The tree-based mechanism is not free. Three trade-offs are worth naming:
- Online vs offline. Verification requires a tree-lookup against the granter’s current state. Offline verifiers must either trust a recent snapshot (with the staleness window as the revocation lag) or refuse to verify until they reconnect. TTL bounds the staleness exposure.
- Selective vs mass. Tier-2 individual revocation is selective but linear in revocations; Tier-3 pool revocation is mass but coarse-grained (the pool is the unit). Deployments compose both.
- Immediate vs eventual. Tree-unbinding is immediate locally: the granter sees the revocation as soon as the emit commits. Propagation to other peers is eventual: they see it when they next consult the granter’s tree (push notifications via subscriptions accelerate this). A revoked capability presented to a peer that has not yet seen the revocation will be accepted; the staleness window is the propagation lag. Deployments that need provably-immediate revocation must combine pool revocation with subscription-based push.
The mechanism handles most production revocation scenarios at low cost; the residual cases (immediate-globally, fully-offline) are handled by extension-level patterns rather than by the substrate.
5. Encryption
Encryption on this substrate is deliberately narrow, and the scope line is the first thing to understand about it. What is specified is stateless, single-shot encryption: an entity is encrypted once, for storage or for one recipient, and the ciphertext stands on its own. Stateful interactive encryption — sessions, streaming, chat, the ratcheting constructions of Signal, Noise, and MLS — is a structurally distinct problem and is a separate piece of work, sharing this substrate rather than extending it. Anything below is about the single-shot half. The other half is real, and it is not here.
The narrowness is deliberate rather than a gap: the design under-promises so that an implementation builds to the threat model actually met, and we follow that discipline rather than smoothing it. What the substrate has not had is use. The mechanisms have conformance vectors, not deployments; nothing here has been exercised against a real adversary, over real time, at real scale. Treat this section as a description of a design that fits the substrate, not as a report from production.
Encryption is independent of authorization. The capability system answers who may act; encryption answers who may understand. Both can apply to the same entity, either can apply without the other, and together they give defense in depth.
5.1. Entity-Level Encryption
An encrypted entity is an entity of type system/encrypted whose data field carries a typed ciphertext. The inner entity ({type, data}) is encrypted as a whole; the type information lives inside the ciphertext, not in the outer envelope. To a peer without decryption capability, the inner type is opaque; to a peer with it, decryption produces the inner entity directly, with its native type and content hash recoverable.
The encrypted entity has its own content hash, derived from its ciphertext bytes. This means the encrypted form is itself addressable, transferable, and integrity-checkable without decryption: a relay peer can route or replicate an encrypted entity without ever seeing its plaintext. The same encrypted entity is the form on the wire, on disk, and in memory — no re-encryption at boundaries, no separate transport-encryption layer.
The decrypted inner entity carries its own (separate) content hash: the hash it had before encryption, derived from its own bytes. So an entity has two identities — the encrypted form’s hash and the plaintext form’s hash — and the two are independent. References can be made to either, depending on which view of the entity is intended.
5.2. Three Modes
Three encryption modes are distinguished by recipient pattern:
Peer mode (single-shot, to one recipient). A specific recipient peer. Hybrid encryption: the inner entity is encrypted under a fresh symmetric key, and the symmetric key is wrapped under the recipient’s encryption subkey via key agreement (X25519). Structurally this is a sealed box — the same shape as crypto_box or age, with sender authentication added. The sender’s ephemeral key is discarded after encryption, so a sender cannot decrypt their own past sends.
It does not provide forward secrecy, and the distinction is worth stating precisely because the mechanism invites the opposite reading. Discarding the sender’s ephemeral key is not forward secrecy against compromise of the recipient. The recipient’s decryption key is long-lived by construction, and the wire carries the sender’s ephemeral public key alongside the ciphertext; anyone who later obtains the recipient’s private half and has kept that pair can recover the shared secret and decrypt. The threat model peer mode actually addresses is passive observation of the relay and storage path — an intermediary that carries the bytes without reading them — not later compromise of the endpoint that received them. Interactive forward secrecy of the kind a ratchet provides belongs to the session work named above, and is not available here.
Self mode (storage). Encryption for one’s own future access. The symmetric key is derived from a long-lived local secret; the same key encrypts and decrypts the entity across sessions. No forward secrecy: a key compromise reveals all past and future self-encrypted entities. The trade-off is intentional: archival storage requires that the holder be able to decrypt old data without preserving ephemeral keys.
Group mode (shared, static). A set of recipients sharing access. A random symmetric key encrypts the entity; the key is wrapped separately for each group member (using peer-mode wrapping). Group membership is then a key-distribution question: adding a member means wrapping the key for them; removing one means re-keying and re-wrapping. Two limits are structural rather than incidental. Re-keying protects future entities only — a removed member keeps the old key and can still decrypt anything they could read before, so removal is not retroactive. And the member set is not hidden: each wrapped key names its recipient, so anyone holding the entity can see who the group is. The cost is linear in group size, and the mode is built for small, stable groups; membership that churns wants the tree-based key agreement of MLS, which is the session work’s territory, not this one’s.
The three modes share the entity-level encrypted-wrapper structure; they differ in how the symmetric encryption key is established. The substrate is neutral: any keying mechanism that produces an authenticated ciphertext fits.
5.3. Recoverability Is the Axis, Not Secrecy
There is a real tension between forward secrecy — communication should stop being decryptable — and durable storage, where data must stay recoverable for as long as its holder needs it. The three modes do not resolve that tension; they sit on one side of it. All three are built so that a holder of the right long-lived key can decrypt later, because all three exist to move or keep data rather than to hold a conversation. What they distinguish is who retains that ability and for how long: self mode for one holder indefinitely, peer mode for one recipient, group mode for a fixed set until the key is rotated forward.
Naming this plainly matters more than claiming the tension away. A design that keeps data recoverable is the right design for storage and transfer, and the wrong one for a conversation that should become unreadable. Resolving the other side needs ratcheting state between two live parties, which is the session work, and it is a different extension for that reason. A deployment chooses a mode per entity rather than per protocol — but every choice on offer here is a choice about recoverability, not about secrecy over time.
5.4. Authorization vs. Confidentiality
Capabilities and encryption are independent dimensions of access. The clearest case is a relay peer:
- The relay holds a capability authorizing it to route messages between named peers. It can read the message envelopes, see source and destination, and forward the message.
- The relay does not hold the decryption key for the messages’ contents. The encrypted inner entity is opaque to it.
This is defense in depth: a relay compromise leaks routing metadata (who is talking to whom) but not message content. A capability compromise allows unauthorized actions but does not reveal encrypted content the attacker lacks keys for. The two compromise classes are independent; an attacker needs both to fully read encrypted communication.
The substrate does not couple the two. A peer can route encrypted entities it cannot read; a peer can decrypt entities it is not authorized to act on. This separation is what lets the capability layer and the encryption layer evolve independently — and what lets deployments mix and match (e.g., authenticated-but-unencrypted internal traffic plus encrypted-for-recipient external traffic) without compounding mechanism.
5.5. What Is Not Yet Settled
The encrypted-wrapper shape, the three-mode framing, the algorithm registries, and the authorization-confidentiality split are settled: algorithms are selected by a versioned byte under a documented registry rather than hardcoded, which is the same discipline the protocol applies to hashes and keys, and a floor suite is mandatory so that two peers always share one. What remains open is genuinely open, and most of it is about what the encrypted form reveals rather than whether it can be read:
- Metadata. Recipient-hiding and size-hiding are identified as work and are not specified. Today an encrypted entity discloses who it is for and roughly how large it is, and group membership is visible on its face. For some deployments that is the more important leak than the plaintext.
- Post-quantum key agreement. A hybrid slot is reserved so the discipline holds and a first implementation has a target, but the construction is not yet realized.
- Distributed key custody. Splitting a backup key across several holders is designed and not built, which leaves key loss a sharper operational risk than the cryptography suggests.
- The session half. Everything interactive — ratcheting, streaming, chat, dynamic groups — sits in the sibling work described at the top of this section. It is the larger unknown of the two, and no part of it is available yet.
Above all of it sits the plainest limitation: none of this has met a real adversary. The mechanisms are specified and checked against conformance vectors, which establishes that implementations agree with each other, not that the design survives contact with use. Cryptographic constructions earn their reputations by being deployed, attacked, and revised. This one has not started.
We describe the structure rather than the choices because the structure is the load-bearing claim: entity-level encryption with three modes, authorization-confidentiality separation, and same-bytes-everywhere. The choices will settle through implementation; the structure already fits the substrate.
6. Deployment Patterns
The substrate provides mechanism. Deployments compose mechanism into patterns. This section describes the patterns that recur across deployment scenarios, organized by the question they answer.
6.1. Identity Presentation
A peer’s identity in deployment is rarely just its peer ID. The standard presentation is a mini-tree envelope:
- The peer keypair entity at the root (
system/peer). - The public key it hashes, in the envelope’s
includedmap. - When the identity extension is installed: the relevant agent cert plus the cert chain back to the trusted quorum (per
EXTENSION-IDENTITY’s peer graph). When it is not: nothing further at the identity layer; recognition is by raw peer ID. - A starting capability the peer is bringing into the connection.
- Optional metadata: display name, organization, contact path.
The envelope is what the peer sends in HELLO. The counterparty verifies the peer keypair entity’s hash, checks the public key matches, validates the cert chain (if present) against its cached quorum-publish for the identity, and accepts the capability if it traces to a root the counterparty trusts.
Human-readable aliases are entities. A directory service is a peer that holds entries of the form alias/{name} → identity_hash, signed by an authority the consumers trust. Aliases are not part of the substrate; they are an application pattern built on the substrate’s primitives.
6.2. Delegation
A capability holder can delegate by issuing a child capability to another peer. The child must be a strict subset of the parent on all four dimensions. Common patterns:
- Sharing for collaboration. The owner of a subtree delegates read access to a collaborator, scoped to the subtree and with a finite TTL. The collaborator’s capability includes the owner’s as its parent and adds caveats (e.g.,
no_delegationto prevent further re-sharing). - Time-boxed access. A short-TTL delegation that auto-expires; useful for temporary consultants, audits, or one-off tasks. The token’s
expires_atfield carries the explicit window. - Capability request flow. The connecting peer sends an
EXECUTEto a capability-issuing handler with a request for the scope it needs. The handler evaluates the request against the connecting peer’s identity, the existing trust relationships, and the deployment’s authorization policy, and issues the capability if the policy allows. The request flow is itself an EXECUTE; there is no separate channel. - Re-delegation chains. Alice delegates to Bob; Bob, holding a delegate-able capability, further delegates to Charlie. Each link must attenuate; the chain depth is bounded by the
max_delegation_depthcaveat. Verifiers walk the full chain.
The patterns share the same mechanism (capability issuance with attenuation) and differ only in the policy that drives them.
6.3. Role-Based Configurations
Different peer roles need different default capability shapes. Concrete patterns:
- IoT sensor. Minimal grant: write access to a specific subtree (the device’s reporting path) and no other handler invocation rights. Identity is a long-lived peer key; capability is renewed periodically (short TTL, ~hours).
- Storage node. Read and write to sync paths shared with replication peers; no execute rights on application handlers. Replicates encrypted content without decrypting it.
- Relay peer. Routing rights only: dispatch operations on
system/relay/*, capability-scoped visibility into which peers it may serve. No content-decryption capability. - Service peer. Handler-focused: implements specific handlers, has a grant that lets it read its configuration subtree and the operational state it needs, and is authorized to invoke a defined set of upstream operations.
- Admin. Broad grant within a cluster boundary, with full audit logging (audit lives on the IM axis; admin actions are entities like any other). Often gated through a quorum of admin peers rather than a single admin peer.
Each is a configuration of capability, encryption, and tree shape. None requires special protocol support; each is composition of substrate features.
6.4. Cluster and Group Patterns
Cluster and group are different concepts in this architecture; the security model treats them differently.
A group is an identity-level concept (per EXTENSION-GROUP). A group is itself an identity — it has its own quorum, its own controller, its own agents, all built from the identity-stack primitives described above. What distinguishes a group from a single-user identity is that its quorum constituents are drawn from members or admins rather than from personal backup keys, and the group’s lifecycle (form, dissolve, merge, split, add/remove member, add/remove subgroup) is exposed through the group handler at system/group. Security-wise, every property of an individual identity — recovery via K-of-N, controller rotation without disturbing contacts, fail-closed validation against cached quorum-publish — applies to a group identity unchanged. Members may act as themselves (their own identity stack) or on behalf of the group (via an acting-on-behalf-of attestation that the group has issued); the two surfaces are distinct.
A cluster is an infrastructure-level concept (the planned system/cluster extension). A cluster coordinates peers at the runtime layer — high-availability, replication, leader election, generation-pool sharing within a trust boundary. Cluster peers typically share a generation pool, and revoking the pool revokes all cluster-internal access in a single tree write. The cluster extension is not yet specified at the same level of detail as identity or group; we treat it as a deployment pattern here rather than as a normative mechanism.
The two compose: a group’s members may run their daily work through a cluster (the user’s laptop, phone, and personal server forming a cluster of agents under the user’s individual identity, all of which are members of the group). The group’s identity manages the recognition surface; the cluster manages the operational shared state.
Trust boundaries are explicit at both levels: a cluster’s pool revocation does not affect another cluster’s pool; a group’s controller revocation does not affect another group’s controller; external delegations from a cluster’s peers do not implicitly cascade through the cluster pool; an agent’s authority within a group is scoped by the group’s role assignments, not by membership alone.
6.5. Information Disclosure
Authorization controls what a peer may do; it also controls what a peer may see. The two are connected through the tree.
- Handler manifest exposure. What a connecting peer can learn about available handlers depends on its initial capability. A minimal initial grant exposes only the connection handler and a request-capability handler; deeper grants expose more of the manifest. The minimum initial grant is by design: a peer with an unknown intent should see only enough to ask for what it needs.
- Capability-scoped views. Reads against the tree are scoped to what the requester’s capability allows. A peer that holds read rights on
data/projects/alpha/*cannot enumeratedata/projects/beta/*— not because the latter is hidden by convention, but because the read attempt fails the resource-scope check. - Metadata leaks. Even with content encrypted, routing metadata (source, destination, timing) is visible to relays. Deployments concerned about metadata exposure use mix-network patterns or onion routing on top of the substrate; the substrate does not provide metadata privacy by itself.
6.6. Incident Response
When something goes wrong, the substrate provides several response patterns:
- Key compromise. Rotate the affected key through the IDENTITY extension’s rotation ceremony —
identity-rotation-handoff(dual-signed) for graceful roll,identity-rotation-recovery(K-of-N quorum signed) when the old key is unavailable. The cert chain advances; predecessor attestations remain in the content store for audit, but the binding moves to the successor cert. If the compromised key was used to sign capability tokens, the relevant generation pool is incremented. - Unauthorized access. Revoke the specific capability via tree unbind, increment the relevant pool, audit the trail via the content store (every action is an emit; every emit is content-addressed; the audit is cryptographic).
- Relay compromise. The encrypted content remains safe. Revoke the relay’s routing grant; rotate any cluster pools the relay had access to; reconfigure routing to other relays. The relay’s content store is forensically preserved; what it routed but could not decrypt is not at risk.
- Cluster compromise. Severity depends on whether internal-trust assumptions broke. The cluster pool is incremented (revokes all cluster-internal access); peer attestations are reviewed; the cluster is rebuilt from the surviving attestation graph if a recovery quorum is available.
Incident response in the entity system uses the same mechanisms as normal operation: tree writes, capability issuance and revocation, attestation updates. There is no separate “break-glass” interface, because break-glass is a generation-pool increment with the right authority.
7. Comparison and Analysis
This section places the entity system’s security model in context: against existing capability systems, against the security philosophies of high-primitive systems, and against the broader landscape analyzed in Convergent Evolution.
7.1. Comparison to Existing Capability Systems
We compare against four systems that represent different stable points in the capability-system design space.
Macaroons (Birgisson et al. 2014) use a contextual-caveat model: a Macaroon is a bearer token plus a chain of caveats, each restricting the bearer’s authority. Caveats are opaque to the protocol — their interpretation lives in the service that issues them. Strengths: flexible attenuation, no central authority for caveat interpretation. Gaps: no four-dimensional grant structure (caveats are general but unstructured), per-service granularity (no handler dimension across services), no peer dimension, no integrated content addressing.
UCAN (Zelenka et al. 2022) is a JWT-based capability format for decentralized contexts: a UCAN has a subject (DID), an ability (operation), a resource (URI), and a proof chain back to a root issuance. UCANs are signed and chainable. Strengths: decentralized issuance, structured delegation, DID-based identity. Gaps: no handler dimension (the resource URI encodes both routing and content), no peer dimension (URIs are location-independent), no content-addressed identity for the tokens themselves (UCANs are referenced by JWT identifier, not content hash).
Biscuit (Couprie et al. 2021) combines Macaroons-style attenuation with a Datalog policy layer: each token can carry a small Datalog program that participates in authorization decisions. Strengths: rich expressiveness for policy, structured attenuation. Gaps: the policy layer is per-token and per-service, not integrated with a substrate; no handler or peer dimensions in the base model; no content addressing.
Zanzibar (Pang et al. 2019) is Google’s centralized authorization system based on relation tuples. Authorization is computed by traversing a relation graph: a subject has a relation to an object via a path through groups, roles, and explicit grants. Strengths: enormous scale, strong consistency guarantees, sophisticated relation algebra. Gaps: centralized (a Zanzibar deployment has authoritative servers); not capability-based (no transferable tokens); no peer dimension (single-domain assumption); no content addressing.
| Dimension | Entity System | Macaroons | UCAN | Biscuit | Zanzibar |
|---|---|---|---|---|---|
| Subject | Yes (IP-pair) | Yes (bearer) | Yes (DID) | Yes (bearer) | Yes (user) |
| Handler | Yes (TX-pair) | — | — | — | — |
| Operation | Yes (EX-pair) | Via caveats | Yes (ability) | Via caveats | Partial (relation) |
| Resource | Yes (TP-pair) | Implicit | Yes (URI) | Implicit | Yes (object) |
| Peer | Yes (XP-pair) | — | — | — | — |
| Time | Yes (token-level) | Via caveats | Yes (exp) | Via caveats | — |
| Delegation | Yes (chain) | Yes (attenuation) | Yes (proof chain) | Yes (attenuation) | — |
| Content-addressed | Yes (IX-pair) | — | — | — | — |
| Decentralized | Yes | Yes | Yes | Yes | No |
The entity system’s distinctive structural contributions are Handler and Peer as first-class grant dimensions, and content-addressed identity for the tokens themselves. The handler dimension lets a capability carry mechanism scoping (“you may invoke this handler”) separate from operation scoping (“you may perform this action”), which existing systems collapse into a single resource-or-service axis. The peer dimension lets a capability carry topology scoping (“you may act on this peer’s tree”), which existing systems treat as a property of the deployment topology rather than as part of the authorization. Content-addressed identity lets the tokens themselves be entities — inspectable, composable, verifiable by hash equality.
7.2. Security Philosophy: What Do You Trust?
Different systems answer the question “what is the unit of trust?” differently. The answers are not feature-level differences; they are philosophical commitments about how security is supposed to work.
“Trust the code.” Holochain’s model: every peer runs identical validation code (the DNA), and security comes from code identity. If you and I run the same DNA, we follow the same rules, and the rules are themselves the guarantee. Capabilities in Holochain are per-function, non-delegatable, secret-based: they exist within a DNA’s runtime, not across DNA boundaries. The DNA wall structurally prevents capability migration; capability tokens cannot escape the DNA context that issued them. The model is internally coherent but architecturally incompatible with delegable capability-based authorization: a delegable capability would need to be meaningful across DNAs, which requires content addressing of the capability tokens, which Holochain does not have.
“Trust the steward.” Plan 9 and Inferno’s model: a single trusted operator administers the namespace, and authority flows from the operator’s configuration. Capabilities are not the primary mechanism; access control lives in the file-server’s per-mount permissions. The model works for the deployment context Plan 9 was designed for (research labs and small organizations) and breaks down at scales where no single steward can be globally trusted. The mechanism class is distinct from Holochain’s: Holochain’s wall is architectural (DNA-determinism), Plan 9’s is organizational (centralized stewardship).
“Trust the identity.” The entity system’s model: capability tokens prove what you are authorized to do, regardless of what code you run, by tracing a cryptographic chain to a root capability issued by a peer that owns the relevant resources. Verification is local, per-message, and content-addressed. Identity is content-derived, capability tokens are content-addressed, and the chain is verifiable by anyone with the public keys of the granters. The model rests on the IXP capability triangle, which requires Full I (content-derived identity); a system at I1 cannot host it.
These are not “better” or “worse” relative to each other. They are different architectural commitments about where security lives. Trust-the-code (Holochain) gives strong determinism at the cost of capability migration. Trust-the-steward (Plan 9) gives simple administration at the cost of decentralization. Trust-the-identity (the entity system) gives decentralized capability-based authorization at the cost of requiring Full I and a tree-walk-based revocation mechanism.
7.3. The IXP Triangle as Structurally Privileged Surface
Of the systems analyzed in Convergent Evolution, the entity system is the only one that activates all three pairs of the IXP triangle simultaneously at full strength. The structural reason is the conjunction of three requirements:
- IX active requires capability tokens to be content-addressed entities, so that convergence verification (same hash = same capability) is a structural fact.
- XP active requires cross-peer dispatch to carry capabilities as part of the message, so that authorization is per-message and not session-bound.
- IP active requires peer identity to be content-derived, so that the chain’s references to granter peer IDs are themselves verifiable hashes.
Adjacent systems each have part of the triangle and are missing a critical pair:
- Holochain has IX (DNA-bound capabilities are content-addressed within the DNA) and XP (zome calls carry capabilities), but its IP is degraded: peer IDs do not escape DNA context, so the cross-DNA capability-meaning that the triangle requires cannot exist.
- Urbit has XP (scry and poke dispatch cross-peer) and IP (self-addressed peer IDs), but lacks I in the entity-system sense: no content-addressed entities, so IX cannot activate. Capabilities, if added, would have to be rebuilt on path-rooted identity rather than content-rooted.
- AT Protocol has IP (DIDs) and partial structure for cross-peer trust, but lacks X (no protocol-level dispatch), so the XP pair is latent: handler authority lives in PDS implementations, not in the protocol’s authorization model.
- Bitcoin has IP (content-addressed addresses) and an economic XP analog, but lacks general-purpose X, so its capability model is bounded to economic operations.
The pair-coverage view makes the gap precise. “Capability-based security” is not a single thing; it is the activation of a specific pair-bundle (IX + XP + IP). Systems that have one or two of the pairs implement portions of capability-based security; systems that have all three implement it in full. The entity system’s distinction is not a feature; it is the unique landscape position where the triangle activates simultaneously.
7.4. Security Properties from Content Addressing
Content addressing provides several security properties as structural consequences, not as added features:
- Tamper evidence. Any modification to an entity changes its content hash, which breaks every reference to the original. There is no way to silently modify a content-addressed entity; modification is structurally visible.
- Verifiable delegation. A capability chain is a sequence of content-addressed entities, each referencing its parent by hash. The chain cannot be modified (insert, delete, swap intermediates) without breaking hash references; the verifier reconstructs the chain from the references and checks every link.
- Self-authenticating messages. A signed content-addressed entity is verifiable by anyone with the granter’s public key. The verifier needs no live connection to the granter, no shared session state, no out-of-band coordination. The token is its own proof.
- Cryptographic audit. The content store is append-only along the IM axis. Past actions are reconstructable from their content-addressed records; nothing is silently deleted; revocation is a binding change, not a content deletion.
These properties are not bolted on. They are what content addressing is: identity derived from bytes, with no separate identity-assignment authority. The security model inherits them by being built on the same substrate.
7.5. Algorithm Agility
Three independent format-code namespaces support cryptographic evolution:
- The content-hash format code (
0x00for ECFv1-SHA-256) selects the hash algorithm used in content addressing. - The peer-ID hash format code selects the hash algorithm used in deriving peer IDs from public keys.
- The peer-ID key format code selects the signature algorithm.
A new algorithm can be introduced in any one of these namespaces without changing the others. Connection negotiation determines the per-connection set: each peer presents its supported algorithms in HELLO; the intersection is the active set. New algorithms enter through extension agreement (new format-code allocations); old algorithms phase out through deprecation in the connection-negotiation policy.
The agility is not unbounded. The hash function used for content addressing is a category-(b) structural instantiation (see The Entity System): changing it changes every content-addressed identity, which is a massive coordination event. Adding a new hash algorithm alongside the existing one is straightforward; replacing the existing one is not. The same holds for the peer-ID hash. Signature algorithms are easier to evolve because signatures are per-message and not retroactively re-keyed.
7.6. Limitations
Several limitations are worth naming explicitly.
- No formal security proofs. The argument that attenuation is enforced, that delegation chains are unforgeable, and that the tree-based revocation mechanism is sound rests on the cryptographic properties of the underlying primitives (Ed25519, SHA-256) plus the structural properties of content addressing. We have not constructed formal proofs in a proof system; this is an open direction.
- Clock skew affects TTL-based revocation. TTL bounds rely on synchronized clocks across peers. Clock skew beyond the TTL window can produce premature acceptance or premature rejection. Deployments tighten this with NTP or with overlap windows in their TTL policies.
- Offline peers cannot receive revocation updates. A peer that cannot reach the granter cannot observe a new revocation. Until reconnection, the peer’s stale view may accept revoked capabilities. TTL bounds the exposure window; the substrate does not eliminate it.
- Selective intermediate revocation requires Tier 2+. The substrate provides root-capability revocation cheaply; revoking a specific intermediate in a chain (without revoking the root) requires per-token tracking, which is Tier 2 work. Deployments that need fine-grained intermediate revocation accept the per-token cost.
- Encryption is specified but untried, and half of it is not specified at all. As the encryption section sets out, what exists covers stateless single-shot use; interactive session encryption is separate, later work. Within what exists, metadata protection (recipient-hiding, size-hiding) and distributed key custody are open, and none of it has deployment experience. Peer mode in particular does not provide forward secrecy against compromise of the recipient’s key, and should not be read as end-to-end encryption in the sense a messaging application means it.
- The role extension is still settling.
EXTENSION-ROLEis specified but has not yet been through a cross-implementation green round. The role-based authority patterns described in this paper depend on its root-cap shape, and that shape may change before it stabilizes. - No production-scale deployment data. The capability mechanism is implemented across three implementations (Go, Python, Rust) and has been exercised in conformance tests, but no large production deployment has been observed long enough to surface scaling or operational issues at scale.
- 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 methodology this enables is described in The Entity Core Protocol.
8. Related Work
8.1. Capability Systems
The object-capability model originates with Dennis and Van Horn (Dennis and Van Horn 1966); modern treatments include KeyKOS (Hardy 1985), EROS (Shapiro et al. 1999), and seL4 (Klein et al. 2009) at the OS level. The entity system’s tokens-as-content-addressed-entities is a different specialization: tokens are transferable across the wire and across peer boundaries, while object capabilities (in the KeyKOS lineage) are bound to a particular kernel’s object table. Hardware capabilities are explored in CHERI (Watson et al. 2015), with ARM Morello (Arm Ltd. 2022) as a production prototype; CHERI capabilities are per-pointer bounds enforced in hardware, structurally distinct from semantic dispatch-level capabilities but using compatible techniques (tag bits, capability caches, bounds checking).
Decentralized capability tokens have a recent literature. Macaroons (Birgisson et al. 2014) established the contextual-caveat pattern. UCAN (Zelenka et al. 2022) adapted JWT for decentralized capability delegation with DID-based identity. Biscuit (Couprie et al. 2021) added a Datalog policy layer. ZCAP-LD (Sporny and Longley 2022) is a JSON-LD format for chained authorization. The entity system’s contribution to this lineage is the four-dimensional grant (handler, operation, resource, peer) and the content-addressed token, both of which are absent from the existing decentralized-capability literature.
8.2. Authorization Models
The role-based access control literature (RBAC (Sandhu et al. 1996)), attribute-based (ABAC (Hu et al. 2014)), and relationship-based (ReBAC (Fong 2011)) frameworks describe authorization policy at the application level. The entity system’s four grant dimensions map to ABAC attribute classes with finer granularity: Action attributes split into Handler and Operation, Environment attributes split into Peer and Time. The entity system implements something close to ReBAC at the substrate level: capability delegation chains are the relationship graph, and capability-derivation patterns (group membership, role assignment) are relationship-derived authority.
Zanzibar (Pang et al. 2019) represents the high-scale centralized branch of relation-based authorization: a single authoritative system maintains the relation graph and answers authorization queries. The entity system represents the decentralized branch: relations are content-addressed capability chains, and verification is local.
8.3. Decentralized Identity
The W3C Decentralized Identifiers (DID) specification (W3C 2022a) and Verifiable Credentials (W3C 2022b) provide a framework for content-or-key-derived identity in distributed contexts. AT Protocol’s identity model (Kleppmann et al. 2024) uses DIDs in a federated setting. The entity system’s peer-ID format is structurally similar (content-derived from a public key) but more minimal: a 46-character Base58 string rather than a URI. The identity entity layer above peer IDs — self-describing records with controller-cert chains and quorum attestations — is closer in spirit to W3C’s “DID Document” pattern.
8.4. Encryption Protocols
Modern messaging encryption is dominated by Signal Protocol (Perrin and Marlinspike 2016) and its successor Messaging Layer Security (MLS (Barnes et al. 2023)) for group messaging. The Noise framework (Perrin 2018) provides composable encrypted-transport patterns. The entity system’s encryption is structurally simpler than these, and the comparison is only fair once the scopes are lined up: what exists here is same-bytes-everywhere single-shot encryption in three modes, with no separate transport-encryption layer, and the simplicity comes from the substrate — encrypted entities are entities, and the same wrapper works on wire and in storage. Signal and MLS solve the problem this deliberately does not: ratcheting state between live parties, which buys forward and future secrecy and dynamic group membership. That is the sibling session work, not a weaker version of it delivered here, and until that work lands the honest comparison is between a sealed box and a session protocol rather than between two session protocols.
8.5. Tagged and Capability Hardware
The Burroughs B5000 (1961) introduced tagged memory with hardware-enforced type checks. KeyKOS (Hardy 1985) and EROS (Shapiro et al. 1999) are software predecessors of modern capability OSes. seL4 (Klein et al. 2009) is formally verified and provides strong isolation guarantees. CHERI (Watson et al. 2015) brings capability hardware to general-purpose computing; ARM Morello and University of Cambridge research prototypes demonstrate the approach. The entity system’s capability model operates at a higher semantic level (per-dispatch authorization rather than per-pointer bounds), but the hardware techniques (capability caches, tag bits, bounds checking) are directly applicable for hardware acceleration; The Entity Machine Boundary sketches how an entity-native processor would integrate capability verification into the dispatch pipeline.
8.6. Content-Addressed Security
Git (Torvalds 2005) provides signed commits over a content-addressed object store. IPFS (Benet 2014) uses content identifiers (CIDs) for distributed content addressing. Nix store paths (Dolstra et al. 2004) are content-addressed build outputs. None of these systems integrates content addressing with capability-based authorization at the protocol level; they provide content addressing as a storage / distribution primitive and leave authorization to other layers.
8.7. Limitations of Coverage
This related-work survey is selective. Deeper engagement with the formal capability literature (Drossopoulou and Noble’s reasoning frameworks, the type-systems treatment of capabilities), the MLS draft and its predecessors, the CHERI security model in detail, and the wider decentralized-identity ecosystem would strengthen the comparison. The selections here aim at the structurally closest systems; a fuller survey would expand the comparison without changing the structural argument.
9. Conclusion
The entity system’s security architecture is built from the same six primitives that define the system. Capabilities are entities; identities are entities; revocation is a binding change; encryption wraps entities and preserves their identity. There is no separate security substance because the substrate is the security substrate.
The architecture is structurally distinctive in several ways:
- Four-dimensional grants (handler, operation, resource, peer) cover the per-grant scope axis with uniform pattern matching. They sit inside an eight-primitive authorization structure (the four per-grant scopes plus four per-token primitives: subject, authority, attenuation, and context-temporal, with revocation as a separate lifecycle mechanism). The decomposition is derived in Dimensional Completeness from analysis of the attribute structure of distributed-system requests; the four per-grant axes are a principled subset, not an arbitrary count.
- Attenuation by construction: child capabilities are provably subsets of parents on all four dimensions. Cryptographic chain references prevent amplification without forging an intermediate granter’s signature.
- Tree-based revocation: revoking a capability is unbinding it from the active set. No blacklist accumulation; the IM/TM split keeps audit and revocation on independent emit axes. Generation pools give O(1) scoped mass revocation.
- Self-describing identities: peer IDs are content-derived; peer keypair entities and (when the identity extension is installed) cert chains compose into mini-trees that travel with the peer; algorithm agility is built into three independent format-code namespaces.
- Entity-level encryption: the same encrypted entity on wire, disk, and in memory, with three modes (self, peer, group) covering storage, single-recipient transfer, and shared archives. Authorization and confidentiality are independent dimensions. Interactive session encryption is separate work and is not part of this.
Structurally, security in the entity system lives at the IXP capability triangle (see The Entity System). The triangle’s three pairs (IX, XP, IP) carry the substrate of capability-based security: content-addressed tokens (IX), cross-peer dispatch carrying tokens (XP), content-addressed peer identity (IP). Two of these are phase-transition pairs that require Full I to activate: capability-based security in the entity-system sense is impossible without content-derived identity, regardless of how richly a grant structure is specified. Of the systems analyzed in Convergent Evolution, the entity system is the only one that activates the full triangle simultaneously.
Three open invitations to refute the closure claims sit alongside the model. An authorization need that requires a fifth grant dimension — a request attribute that is not subject, handler, operation, resource, peer, time, or delegation, and that is not expressible through the existing four-dimensional grant plus the token-level fields — would mean the dimensionality is wrong. A revocation scenario that tree-based revocation plus generation pools plus TTL does not cover at acceptable cost would expose a trade-off envelope the mechanism cannot reach; the trade-offs (online vs offline, selective vs mass, immediate vs eventual) are real, and a scenario outside the envelope would be informative. An attenuation attack that amplifies without forging an intermediate granter’s signature would invalidate the cryptographic construction. None has been identified.
Open questions remain. Formal security proofs of attenuation and chain unforgeability are an obvious next step; the discrete, finite structures of the capability model are well-suited to a proof system like Coq or Lean. Production-scale deployment data is the other major gap: the model has been validated in implementations and conformance tests but not in long-running production environments. The encryption work needs implementation experience on the half that exists and a specification for the interactive half that does not. The role extension’s shape needs cross-implementation green-round confirmation. Each of these is in motion; none is a blocker for the substrate-level claims this paper makes.
The security model has been under reduction throughout the protocol’s evolution. The wire format has not changed; the four-dimensional grant has not changed; the tree-based revocation mechanism has not changed. What has changed is the type system around them — new caveat types, new attestation formats, new role-derivation patterns. The pattern matches the broader system’s pattern (see The Entity System; The Entity Core Protocol): the protocol shrinks, the type system grows. Security is no exception.