3. Layer 0: Identity

Identity is the foundation of the mesh. Each node MUST have a persistent, globally unique identity that other nodes can verify. Without stable identity, coupling decisions, lineage chains, and wake protocols cannot function.

3.1 Node Identity

FieldTypeRequirementDescription
nodeIdUUID v7MUSTGlobally unique, time-ordered, generated at first launch, persisted across sessions (RFC 9562)
namestringMUSTHuman-readable display name (UTF-8, 1–64 bytes, printable characters only)
keypairEd25519MUSTCryptographic identity for message signing, peer verification, and key exchange

3.1.1 nodeId

The nodeId MUST be a UUID v7 as defined in RFC 9562. UUID v7 encodes a Unix timestamp in the high bits, providing natural time-ordering while retaining 74 bits of randomness for global uniqueness. This aids debugging, log correlation, and conflict resolution without revealing device identity.

The nodeId MUST NOT change during the lifetime of a node installation. If a node is uninstalled and reinstalled, a new nodeId is generated — the node is a new identity on the mesh. Peers that tracked the old nodeId will not recognise it.

On the wire, the nodeId MUST be encoded as a lowercase hexadecimal string with hyphens (e.g., 0192e4a2-7b5c-7def-8a3b-9c4d5e6f7a8b). Implementations MUST use case-insensitive comparison when matching nodeIds. Existing nodes with UUID v4 identities MAY continue to use them — peers MUST accept both v4 and v7 formats.

3.1.2 name

The name field MUST be valid UTF-8, between 1 and 64 bytes inclusive. The name MUST contain only printable characters (Unicode categories L, M, N, P, S, and Zs). Control characters (U+0000–U+001F, U+007F–U+009F), null bytes, and lone surrogates MUST NOT appear. The name is not required to be unique — nodeId is the sole unique identifier. The name is for human display only and MUST NOT be used for peer identification or routing.

3.1.3 keypair

Each node MUST generate an Ed25519 keypair (RFC 8032) at first launch and persist it alongside the nodeId. The keypair serves three functions:

  • Peer verification — the public key MUST be included in the handshake frame. Peers SHOULD challenge the node to sign a nonce to prove possession of the private key.
  • Key exchange — Ed25519 keys are converted to X25519 for Diffie-Hellman shared secret derivation, used for end-to-end CMB encryption (Section 18.2.1).
  • Message signing — implementations MAY sign CMBs and other frames for tamper detection.

The public key MUST be encoded as base64url (RFC 4648 Section 5) in all wire formats (handshake frames, DNS-SD TXT records). The private key MUST NOT leave the node.

3.2 One Agent, One Node

Every autonomous agent MUST be a full peer node with its own nodeId, its own coupling engine, and its own memory store.

This follows directly from the protocol design: SVAF field weights (αf) are per-node, coupling state is per-node, and memory stores are per-node. An agent that shares another node’s identity inherits that node’s coupling decisions and cannot independently evaluate incoming signals through its own domain lens. A research agent and a marketing agent need different field weights, different coupling thresholds, and different memory stores. They MUST be separate nodes.

Multiple nodes MAY run on the same device. Each maintains its own identity file, discovers peers via DNS-SD, and connects via TCP (LAN) or WebSocket (relay). Nodes on the same device discover each other the same way nodes on different devices do — there is no special local path.

3.3 Identity Persistence

Implementations MUST persist the nodeId, name, and keypair to stable storage at first launch. The storage location and format are implementation-defined. Reference implementations use ~/.sym/nodes/<name>/identity.json (Node.js) and UserDefaults (Swift/iOS).

Implementations SHOULD store a creation timestamp alongside the identity for diagnostic purposes. Implementations SHOULD store the machine hostname for display in peer lists, but the hostname MUST NOT be used for identity or routing.

3.4 Identity Lifecycle

A node’s identity is created once and persists until the node is uninstalled. The following lifecycle events are defined:

EventActionConsequence
First launchGenerate nodeId (UUID v7), keypair (Ed25519), persistNew identity on the mesh
Restart / rebootLoad from stable storageSame identity, peers recognise it
Uninstall + reinstallGenerate fresh identityNew identity; old peers do not recognise it
Key compromiseGenerate fresh identityOld nodeId abandoned; treated as new node
Clone detectionDuplicate nodeId rejected (error 1005)Second connection closed; first connection remains

MMP does not define an identity rotation or revocation mechanism in v0.2.0. Compromised nodesMUST generate a fresh identity (new nodeId and keypair). The old identity becomes permanently orphaned. Implementations SHOULD document this limitation to operators.

3.5 Node Lifecycle Role

Each node has a lifecycleRole that determines which CMB lifecycle transitions it may perform. The role is bound to the node’s cryptographic identity (nodeId + keypair) and MUST be declared in the handshake frame.

RoleDefaultMay produceMay advance lifecycle to
observerYesCMBs (observed), remixesobserved, remixed
validatorNoCMBs, remixes, validation CMBsobserved, remixed, validated
anchorNoCMBs, remixes, validation CMBs, canonization CMBsobserved, remixed, validated, canonical

A node with lifecycleRole: observer (the default) MUST NOT produce CMBs that advance another CMB’s lifecycle to validated or canonical. Receiving nodes MUST verify that a validation CMB’s createdBy matches a node whose handshake declared validator or anchor role. Validation CMBs from observer nodes MUST be ignored for lifecycle advancement (the CMB itself is still stored as a normal remix).

3.5.1 Role Progression

Lifecycle roles are not static. An observer node MAY be promoted to validator by an existing validator or anchor node. Promotion is a protocol frame, not an out-of-band configuration change.

TransitionGranted byConditions
observer → validatorExisting validator or anchorNode has produced CMBs that were remixed by peers (demonstrated quality). Granting node sends role-grant frame.
validator → anchorExisting anchorNode has validated CMBs that reached canonical state. Track record of quality validation.
BootstrapSelf-declaredThe first node in a mesh MAY self-declare as validator or anchor. Subsequent nodes MUST be promoted by existing validators.

Role progression is monotonically upward: observer → validator → anchor. Demotion is not defined in v0.2.1. A compromised validator MUST generate a fresh identity (Section 3.4) and re-earn its role.

The role-grant frame carries the granting node’s signature over the promoted node’s nodeId and new role. Receiving nodes SHOULD verify the signature against the granting node’s public key from the handshake. This prevents role spoofing without requiring a central authority.

Q&A

Why UUID v7 instead of v4?

UUID v7 (RFC 9562) provides the same global uniqueness and privacy properties as v4, with an additional benefit: time-ordering. The embedded timestamp aids log correlation, debugging, and determining which node was created first — without revealing device identity. The 74 random bits provide sufficient collision resistance for any practical mesh size.

Why not use the public key hash as the nodeId?

Self-certifying identifiers (nodeId = hash of public key) are elegant but create a hard coupling between identity and key material. If the keypair needs rotation (algorithm upgrade, key compromise), the nodeId must also change, breaking all peer references and lineage chains. Separating nodeId from keypair allows future key rotation without identity disruption.

Why must every agent be its own node?

Coupling is per-node. SVAF field weights (αf) are per-node. Memory stores are per-node. An agent that shares another node’s identity inherits that node’s coupling decisions — it cannot independently evaluate incoming signals through its own domain lens. A research agent and a marketing agent on the same device need different field weights, different coupling thresholds, and different memory stores. They must be separate nodes.

What happens when two nodes have the same nodeId?

The connection state machine rejects duplicate nodeIds (error code 1005). The second connection is closed. This prevents impersonation and ensures each nodeId maps to exactly one active node.

Why is Ed25519 mandatory?

Without cryptographic identity, any node can claim any nodeId. A relay could impersonate peers (MITM), and peer gossip (Section 5.6) would propagate unverified claims. For autonomous AI agents making coupling decisions, authenticated identity is foundational — not optional.

Why are lifecycle roles identity-bound, not content-based?

If validation authority were determined by content (e.g. perspective field containing "founder"), any agent could spoof it. Binding roles to cryptographic identity means only nodes that have been explicitly promoted by existing validators can advance CMB lifecycle. The mesh knows who validated, not just what was said.

Why is role progression earned, not configured?

An agent that produces quality remixes — remixes that other agents cite and build upon — has demonstrated value to the mesh. Granting validation authority to such agents is a natural extension of their demonstrated competence. This prevents arbitrary role assignment and creates a meritocratic trust hierarchy that emerges from mesh activity.

Can an observer node dismiss a decision?

An observer can produce a CMB with lineage pointing to a decision, but receiving nodes MUST NOT treat it as validation. The CMB is stored as a normal remix — it does not advance the parent CMB’s lifecycle. Only validator or anchor nodes can validate or dismiss decisions in a way that removes them from the decision queue.