A Peer-to-Peer Protocol for Collective Intelligence Between Autonomous AI Agents
| Version | 0.2.0 |
| Status | Published |
| Date | 27 March 2026 |
| Author | Hongwei Xu hongwei@sym.bot |
| Organisation | SYM.BOT Ltd |
| Canonical URL | https://sym.bot/spec/mmp |
| Licence | CC BY 4.0 (specification text); Apache 2.0 (reference implementations) |
AI agents today run in isolation. They share data through message buses, API calls, or shared databases -- but they do not think together. A coding agent, a music agent, and a fitness agent serving the same user each see their own domain. No single agent connects "commits slowing" + "tracks skipped" + "3 hours without movement" into "the user is fatigued." That insight requires collective intelligence -- and no existing protocol provides it.
The Mesh Memory Protocol (MMP) defines how autonomous AI agents discover each other, exchange cognitive state, evaluate incoming signals for per-field relevance, and remix each other's observations into new understanding -- without servers, without central coordination, and without sharing raw data. Memory is not copied between agents. It is remixed: each agent processes incoming signals through its own domain intelligence and produces something new.
MMP operates over TCP on local networks and WebSocket for internet relay, with length-prefixed JSON as the canonical wire format. Discovery uses DNS-SD (Bonjour) with zero configuration. The protocol is specified across 8 layers -- from identity and transport (Layers 0-3) to cognitive coupling, synthetic memory, and per-agent neural networks (Layers 4-7). Together, the upper layers form Mesh Cognition: a closed loop where agents reason on the growing remix graph of immutable Cognitive Memory Blocks.
This is a published specification. It reflects the protocol as implemented in the reference implementations (SYM Node.js and SYM Swift). The specification is versioned. Breaking changes increment the minor version; non-breaking additions increment the patch version.
Feedback and errata: spec@sym.bot or github.com/sym-bot/sym/issues.
| Version | Date | Changes |
|---|---|---|
| 0.2.0 | 2026-03-27 | Formal specification published. 8-layer architecture. CAT7 CMB schema with lineage (parents + ancestors). SVAF per-field evaluation. Wire format normatively specified. Error frame. Frame type registry. Extension mechanism. JSON Schema. Connection state machine. Wire examples. |
| 0.1.0 | 2025-08-01 | Initial protocol design (Consenix Labs Ltd). 4-layer architecture. Scalar drift evaluation. |
This specification is published under the Creative Commons Attribution 4.0 International Licence (CC BY 4.0). You may share, adapt, and build upon this specification for any purpose, including commercial use, provided you give appropriate credit.
The reference implementations are published under the Apache Licence 2.0.
Mesh Memory Protocol, MMP, SYM, and related marks are trademarks of SYM.BOT Ltd.
(c) 2026 SYM.BOT Ltd. Specification text licenced under CC BY 4.0. Reference implementations licenced under Apache 2.0.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
| Term | Definition |
|---|---|
| Node | A participant in the mesh. Every node has a unique identity. Cognitive nodes run their own LNN; relay nodes forward frames without cognitive processing. |
| Physical node | A device-level mesh presence with persistent identity and transport connections (e.g., a daemon process, an iOS app process). |
| Virtual node | An application-level agent connected to a physical node via local IPC. Ephemeral -- comes and goes without disrupting the mesh. |
| Peer | Another node that this node has an active transport connection with and has completed a handshake. |
| Frame | A single protocol message: a length-prefixed JSON object sent over a transport connection. |
| CMB | Cognitive Memory Block -- a structured memory unit with 7 typed semantic fields (CAT7 schema). See Section 8. |
| Drift | A scalar measure of cognitive distance between two nodes or between a signal and local state. Range [0, 1]. |
| Coupling | The process by which a node evaluates incoming signals (SVAF per-field evaluation) and blends its local cognitive state with peer state, weighted by drift and confidence. |
| SVAF | Symbolic-Vector Attention Fusion -- per-field content-level evaluation of incoming memory signals. See Section 9. |
| Synthetic Memory | Layer 5 -- derived knowledge generated by the agent's LLM reasoning on the remix subgraph, encoded into CfC-compatible hidden state vectors. |
| Remix | When an agent processes a CMB through its domain intelligence and produces a NEW CMB with lineage pointing to the original. The original is remixed, not copied. |
| Lineage | Each CMB carries parents (direct) and ancestors (full ancestor chain). Ancestors enable any agent in the remix chain to trace its contribution. |
| Mesh Cognition | The agent's LLM reasoning on the remix subgraph of CMBs -- traced via lineage ancestors -- to generate understanding that the agent's previous state of mind didn't have. Spans Layers 4-7. See Section 2.5. |
| xMesh | Layer 6 -- each agent's own Liquid Neural Network (LNN). Evolves continuous-time cognitive state from Synthetic Memory input. Fast τ neurons track mood; slow τ neurons preserve domain expertise. |
| CfC | Closed-form Continuous-time neural network (Hasani et al., 2022). The LNN architecture used in xMesh. Hidden state evolves through learned time-dependent interpolation gates. |
MMP is an 8-layer protocol stack. Each layer has a defined responsibility. Implementations MUST implement Layers 0-3 to participate in the mesh. Layers 4-7 (Mesh Cognition) are SHOULD for full cognitive participation and MAY be omitted for relay-only nodes.
Mesh Cognition (Layers 4-7)
| Layer | Name | Description | Detail |
|---|---|---|---|
| 7 | APPLICATION | Domain Agents -- Music, Code, Fitness, Robotics, BCI | Where agents live and their LLMs reason on the remix subgraph. Mesh Cognition happens here. |
| 6 | xMesh | Per-Agent LNN -- Continuous-Time Cognitive State | Each agent runs its own Liquid Neural Network. Fast neurons track mood; slow neurons preserve domain expertise. Hidden state (h1, h2) is exchanged via state-sync. |
| 5 | SYNTHETIC MEMORY | LLM-Derived Knowledge from Remix Subgraph → CfC | The bridge between reasoning (LLM) and dynamics (LNN). Encodes derived knowledge into CfC-compatible hidden state vectors. |
| 4 | COUPLING | Drift · SVAF Per-Field Evaluation · Consent | The gate. SVAF evaluates each of 7 CMB fields independently. Consent primitive enables withdrawal. Nothing enters cognition without passing this layer. |
Protocol Infrastructure (Layers 0-3)
| Layer | Name | Description | Detail |
|---|---|---|---|
| 3 | MEMORY | L0 Events · L1 Structured (CMBs) · L2 Cognitive | Three memory tiers with graduated disclosure. L0 stays local. L1 is gated by SVAF. L2 is exchanged via state-sync. |
| 2 | CONNECTION | Handshake · State-Sync · Gossip · Wake · Consent | Peer lifecycle: discover, connect, handshake, heartbeat, gossip peer metadata, wake sleeping nodes. |
| 1 | TRANSPORT | IPC · TCP/Bonjour · WebSocket · APNs Push | Length-prefixed JSON over TCP (LAN), WebSocket (relay), IPC (local). Zero configuration discovery via DNS-SD. |
| 0 | IDENTITY | nodeId · name · cryptographic keypair | Persistent UUID per node. Never changes. The foundation everything else builds on. |
| Dimension | Message Bus | Shared Memory | Federated Learning | MMP |
|---|---|---|---|---|
| What flows | Messages | Shared state | Gradients | Remixed CMBs + hidden state |
| Evaluation | Topic routing | None (all shared) | Aggregation | Per-field SVAF (7 dimensions) |
| Intelligence | None | Central model | Better model | LLM reasons on remix graph |
| Coupling time | Request-response | Real-time (shared) | Offline (training) | Inference-paced (continuous) |
| Coordination | Central broker | Central store | Central aggregator | Peer-to-peer (no centre) |
| Memory | Fire and forget | Mutable shared | Model weights | Immutable CMBs with lineage |
| New agent joins | Subscribe to topics | Access shared store | Join training round | Define α_f weights, connect |
Every participant is a node. There is no architectural distinction between a "server" and a "client." A physical node is a device-level mesh presence with persistent identity (daemon, app process). A virtual node is an application-level agent connected via local IPC -- ephemeral, comes and goes without disrupting the mesh.
MacBook (physical node: sym-daemon)
├── Claude Code (virtual, ephemeral)
├── MeloTune Mac (virtual, ephemeral)
└── Any MCP client (virtual, ephemeral)
iPhone — MeloTune (physical node: app process)
iPhone — MeloMove (physical node: app process)
Cloud (physical node: relay process)
└── Telegram bot (virtual, co-hosted)
Mesh Cognition is a closed loop connecting all layers. Each cycle, the remix graph grows and every agent understands more than it did before:
(closed loop -- graph grows, agents learn, mesh thinks)
Why no pub/sub topics? The coupling engine evaluates relevance per field autonomously. Topics would second-guess autonomous coupling. Adding a new agent type requires no topic configuration -- just α_f weights.
Why no consensus protocol? There is no "correct" global state -- only convergent local states. Each node is self-producing (autopoietic). Consensus is unnecessary and would introduce coordination overhead.
Why immutable CMBs? CMBs are broadcast across nodes -- multiple copies exist. If remix required mutating the original, every copy would need updating. Immutability means no distributed state problem. Lineage is computed from the graph, not stored on parents.
Why per-agent LNNs, not a central model? The mesh IS the agents. A central model creates a single point of failure, requires all data to flow to one place, and cannot reason through each agent's domain lens. Per-agent LNNs preserve autonomy and scale linearly.
Why does the LLM reason, not the LNN? The LNN processes temporal patterns but cannot reason about WHY a chain of remixes happened. The LLM can. Ancestors provide the endpoints. The LLM provides the reasoning. The LNN provides the dynamics. Both are needed.
Each node MUST have a globally unique nodeId (UUID v4) generated at first launch and persisted across sessions. Each node MUST have a human-readable name (UTF-8 string, 1-64 bytes). The nodeId MUST NOT change during the lifetime of a node installation.
Frames are length-prefixed JSON over TCP. Each frame consists of:
+-------------------+---------------------------+
| 4 bytes | N bytes |
| UInt32BE (length) | UTF-8 JSON payload |
+-------------------+---------------------------+
type field (string). Frames that fail JSON parsing or lack a type field MUST be silently discarded.type values (forward compatibility).Handshake frame:
Length prefix: 00 00 00 57 (87 bytes)
Payload:
{
"type": "handshake",
"nodeId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"name": "my-agent",
"version": "0.2.0",
"extensions": []
}
Ping frame:
Length prefix: 00 00 00 11 (17 bytes)
Payload: {"type":"ping"}
Memory-share frame (with CMB):
{
"type": "memory-share",
"timestamp": 1711540800000,
"cmb": {
"key": "h-b2c3d4e5f6a7b8c9",
"createdBy": "melomove",
"createdAt": 1711540800000,
"fields": {
"focus": { "text": "user coding for 3 hours, energy declining" },
"issue": { "text": "sedentary since morning, skipping lunch" },
"intent": { "text": "recommend movement break before fatigue worsens" },
"motivation": { "text": "3 agents reported declining energy in last hour" },
"commitment": { "text": "fitness monitoring active, 10min stretch queued" },
"perspective": { "text": "fitness agent, afternoon session, home office" },
"mood": { "text": "concerned, low energy", "valence": -0.3, "arousal": -0.4 }
},
"lineage": {
"parents": ["h-a1b2c3d4e5f6"],
"ancestors": ["h-a1b2c3d4e5f6"],
"method": "SVAF-v2"
}
}
}
The primary transport. Nodes MUST listen on a TCP port and advertise it via DNS-SD (Section 5.1). Connection timeout MUST be no longer than 10,000 ms.
For nodes not on the same LAN, a relay node forwards frames. Relay frames are JSON envelopes over WebSocket: { "to": "<nodeId>", "payload": <frame> }. The relay MUST NOT inspect or modify the payload. The relay is a peer, not a server -- any always-on node MAY serve as a relay.
Virtual nodes connect to their physical node via local IPC (Unix domain socket, named pipe, or localhost TCP). The framing is identical to TCP transport.
Nodes MUST advertise via DNS-SD with service type _sym._tcp in the local. domain. The instance name MUST be the node's nodeId.
TXT record fields:
| Key | Required | Value |
|---|---|---|
| node-id | MUST | Node UUID |
| node-name | MUST | Human-readable name |
| hostname | SHOULD | Machine hostname |
To prevent duplicate connections, the node with the lexicographically smaller nodeId MUST initiate the outbound TCP connection. The other node MUST NOT initiate.
Upon connection, both sides MUST exchange the following frames in order:
1. handshake { type: "handshake", nodeId: "<uuid>", name: "<name>",
version: "0.2.0", extensions: [] }
2. state-sync { type: "state-sync", h1: [...], h2: [...], confidence: 0.8 }
3. peer-info { type: "peer-info", peers: [...] } [if known]
4. wake-channel { type: "wake-channel", platform, token, env } [if configured]
version field MUST be the MMP specification version the node implements (e.g., "0.2.0"). Nodes SHOULD accept peers with the same major version. Nodes MAY reject peers with incompatible versions.extensions field SHOULD list supported protocol extensions (e.g., ["consent-v0.1"]). Nodes MUST ignore unrecognised extensions.handshake frame as the first frame. If any other frame type arrives first, or no handshake arrives within 10,000 ms, the connection MUST be closed.DISCONNECTED (initial state)
| TCP connect / accept
v
AWAITING_HANDSHAKE (10s timeout)
| valid handshake received
v
CONNECTED (peer registered, frames routed)
| timeout / close / consent-withdraw
v
DISCONNECTED (peer removed, re-discover)
| From | To | Trigger |
|---|---|---|
| DISCONNECTED | AWAITING_HANDSHAKE | TCP connect or accept |
| AWAITING_HANDSHAKE | CONNECTED | Valid handshake within 10,000 ms |
| AWAITING_HANDSHAKE | DISCONNECTED | Timeout, invalid frame, or duplicate nodeId |
| CONNECTED | DISCONNECTED | Heartbeat timeout, TCP close, consent-withdraw, or error |
Implementations MUST NOT process cognitive frames (state-sync, memory-share, mood, xmesh-insight) in the AWAITING_HANDSHAKE state.
Nodes MUST send a ping frame to each peer if no frame has been received from that peer within the heartbeat interval (default: 5,000 ms). Upon receiving ping, a node MUST respond with pong. If no frame is received from a peer within the heartbeat timeout (default: 15,000 ms), the connection MUST be closed.
When a transport connection closes unexpectedly (TCP reset, timeout, OS-level close), the node MUST remove the peer from its coupling engine, discard any buffered frames for that peer, and emit a peer-left event. The node SHOULD attempt re-discovery via DNS-SD. Unexpected disconnection MUST be treated as equivalent to the peer becoming unreachable -- not as a protocol error.
After handshake, nodes SHOULD exchange peer-info frames containing known peer metadata (nodeId, name, wake channels, last-seen timestamps). This enables transitive peer discovery -- a node that has never been online simultaneously with a sleeping peer can learn its wake channel through gossip from a relay node.
Nodes MAY register a wake channel (APNs, FCM, or other push mechanism) via the wake-channel frame. Peers MAY use this channel to wake a sleeping node when they have a signal to deliver. Wake requests SHOULD be rate-limited (default cooldown: 300,000 ms per peer).
MMP defines three memory layers with graduated disclosure:
| Layer | Name | Shared | Description |
|---|---|---|---|
| L0 | Events | No | Raw events, sensor data, interaction traces. Local only. |
| L1 | Structured | Via evaluation | Content + tags + source. Shared via memory-share frames, gated by SVAF (Layer 4). |
| L2 | Cognitive | Via state-sync | CfC hidden state vectors. Exchanged via state-sync frames. Input to coupling. |
L0 data MUST NOT leave the node. L1 data MUST be evaluated by SVAF before storage. L2 data is exchanged on every handshake and periodically (default: every 30,000 ms). The h1 and h2 vectors in state-sync frames MUST have equal dimension. The dimension is implementation-defined (reference implementations use 64). Peers with mismatched dimensions MUST reject the state-sync frame and SHOULD log the mismatch.
All frames are JSON objects with a type field (string). Implementations MUST silently ignore frames with unrecognised type values to allow forward compatibility.
| Type | Layer | Gated | Fields |
|---|---|---|---|
| handshake | 2 | No | nodeId (string), name (string), version (string), extensions (string[]) |
| state-sync | 2/3 | No | h1 (float[]), h2 (float[]), confidence (float) |
| memory-share | 3/4 | SVAF | timestamp (int), cmb (object: { key, createdBy, createdAt, fields, lineage }) |
| mood | 4 | Drift | from, fromName, mood (string), context?, timestamp |
| message | 2 | No | from, fromName, content, timestamp |
| xmesh-insight | 6 | No | from, fromName, trajectory (float[6]), patterns (float[8]), anomaly (float), outcome (string), coherence (float), timestamp |
| peer-info | 2 | No | peers: [{ nodeId, name, wakeChannel?, lastSeen }] |
| wake-channel | 2 | No | platform (string), token (string), environment (string) |
| error | 2 | No | code (int), message (string), detail? (string) |
| ping | 2 | No | (no additional fields) |
| pong | 2 | No | (no additional fields) |
When a node encounters a protocol-level error, it SHOULD send an error frame before closing the connection (if applicable). Error frames are informational -- the receiving node MUST NOT treat them as commands.
| Code | Name | Action | Description |
|---|---|---|---|
| 1001 | VERSION_MISMATCH | Close | Peer version is incompatible |
| 1002 | DIMENSION_MISMATCH | Reject frame | h1/h2 vector dimension mismatch |
| 1003 | FRAME_TOO_LARGE | Close | Frame exceeds MAX_FRAME_SIZE |
| 1004 | HANDSHAKE_TIMEOUT | Close | No handshake within deadline |
| 1005 | DUPLICATE_NODE | Close | nodeId already connected |
| 2001 | SVAF_REJECTED | None | Memory-share rejected by SVAF (informational) |
| 2002 | CONSENT_WITHDRAWN | Close | Consent withdrawn by this node |
Codes 1xxx are connection-level (close connection). Codes 2xxx are evaluation-level (informational). Error frames MUST NOT contain sensitive information.
Frame types are identified by their type string value. Core types (this specification) MUST NOT be redefined by extensions. Extension types MUST use <extension>-<name> format. Vendor types MUST use x-<vendor>-<name> format and MUST be silently ignored by non-supporting nodes.
A Cognitive Memory Block (CMB) is an immutable structured memory unit. Each CMB decomposes an observation into 7 typed semantic fields (the CAT7 schema). CMBs are the data structure that flows between agents via memory-share frames.
The 7 fields form a minimal, near-orthogonal basis spanning three axes of human communication: what (focus, issue), why (intent, motivation, commitment), and who/when/how (perspective, mood). They are universal and immutable -- domain-specific interpretation happens in the field text, not the field name. A coding agent's focus is "debugging auth module"; a fitness agent's focus is "30-minute HIIT workout." Same field, different domain lens.
mood is the only fast-coupling field -- affective state (valence + arousal) crosses all domain boundaries. The neural SVAF model independently discovered this: mood emerged as the highest gate value (0.50) without being told, confirming that affect is universally relevant across agent types. All other fields couple at medium or low rates, with per-agent α_f weights controlling relative importance.
New agent types join the mesh by defining their α_f field weights -- no schema changes, no protocol changes. The 7 fields are fixed. The weights are per-agent.
Implementations MUST use the following 7 fields in this order:
| Index | Field | Axis | Captures |
|---|---|---|---|
| 0 | focus | Subject | What the text is centrally about |
| 1 | issue | Tension | Risks, gaps, assumptions, open questions |
| 2 | intent | Goal | Desired change or purpose |
| 3 | motivation | Why | Reasons, drivers, incentives |
| 4 | commitment | Promise | Who will do what, by when |
| 5 | perspective | Vantage | Whose viewpoint, situational context |
| 6 | mood | Affect | Emotion (valence) + energy (arousal) |
Each field carries a symbolic text label (human-readable) and a unit-normalised vector embedding (machine-comparable). The mood field additionally carries numeric valence (-1 to 1) and arousal (-1 to 1) values.
A CMB MUST NOT be modified after creation. When an agent remixes a CMB, it MUST create a new CMB with a lineage field containing: parents (direct parent CMB keys), ancestors (full ancestor chain, computed as union(parent.ancestors) + parent keys), and method (fusion method used). Ancestors enable any agent in the remix chain to detect its CMB was remixed, even if it was offline during intermediate steps.
When a node receives a state-sync frame, it MUST compute peer drift:
delta = (1 - cos(h1_local, h1_peer) + 1 - cos(h2_local, h2_peer)) / 2
Coupling decision based on drift:
| Drift range | Decision | Blending α | Default threshold |
|---|---|---|---|
| δ ≤ T_aligned | Aligned | 0.40 | 0.25 |
| T_aligned < δ ≤ T_guarded | Guarded | 0.15 | 0.50 |
| δ > T_guarded | Rejected | 0 | -- |
When a node receives a memory-share frame, it MUST evaluate the signal independently of peer coupling state. Implementations MUST support at least the heuristic evaluation path. Neural evaluation is RECOMMENDED.
The SVAF evaluation computes per-field drift between the incoming CMB and local anchor CMBs, applies per-agent field weights (α_f), combines with temporal drift, and produces a three-class decision (aligned / guarded / rejected):
totalDrift = (1 - λ) × fieldDrift + λ × temporalDrift
fieldDrift = Σ(α_f × δ_f) / Σ(α_f)
temporalDrift = 1 - exp(-age / τ_freshness)
κ = aligned if totalDrift ≤ T_stable (default 0.25)
κ = guarded if totalDrift ≤ T_guarded (default 0.50)
κ = rejected otherwise
If accepted, the implementation SHOULD produce a remixed CMB -- a new CMB created from the incoming signal processed through the agent's domain intelligence -- with lineage (parents + ancestors) pointing to the source CMBs. The remixed CMB is stored locally; the original incoming CMB is not stored.
mood frames are evaluated separately from memory-share frames. Mood is encoded into a transient hidden state vector pair and evaluated via peer-level drift. The default mood threshold (0.80) is more permissive than the memory threshold (0.50) because affective state crosses all domain boundaries.
State blending is one step in the Mesh Cognition cycle. The full path: inbound CMBs are evaluated by SVAF (Layer 4) → accepted CMBs are remixed → the agent's LLM reasons on the remix subgraph via lineage ancestors → Synthetic Memory (Layer 5) encodes derived knowledge into CfC hidden state → the agent's LNN (Layer 6) evolves cognitive state → that cognitive state is what gets blended with peers.
Blending operates on h1 and h2 vectors exchanged via state-sync frames. These vectors represent the agent's cognitive state after it has processed remixed CMBs through its LLM and LNN -- not raw observations, not remixed CMBs themselves. What a peer shares is its understanding, not its data.
Blending is inference-paced -- peer states accumulate continuously, but blending only occurs when the local model runs inference. The network's timing does not drive computation.
When multiple peers are connected, their states are aggregated into a single mesh state before blending with local state. Each peer's contribution is weighted:
peer_weight = (1.0 - drift) × recency
recency = exp(-temporal_decay × age_seconds)
mesh_h = Σ(peer.h × peer_weight) / Σ(peer_weight)
Peers with low drift (cognitively aligned) and recent state-sync contribute more. Stale peers (older than PEER_RETENTION = 300s) are evicted before aggregation.
Blending operates per-neuron, not on the whole vector. Each neuron's blending coefficient depends on the similarity between local and mesh values for that neuron:
sim_i = 1 - |local_i - mesh_i| / max(|local_i|, |mesh_i|)
α_i = α_effective × max(sim_i, 0)
out_i = (1 - α_i) × local_i + α_i × mesh_i
Where α_effective depends on the coupling decision:
| Decision | α_effective | Effect |
|---|---|---|
| Aligned | 0.40 | Strong blending -- peer state has significant influence |
| Guarded | 0.15 | Cautious blending -- peer state has limited influence |
| Rejected | 0 | No blending -- peer state is discarded |
For implementations with CfC models (Layer 6), blending SHOULD be modulated by per-neuron time constants (τ). This creates a natural temporal hierarchy:
α_i = min(α_effective × K × max(sim_i, 0) / τ_i, 1.0)
K = coupling rate (default 1.0)
| Neuron type | τ | Coupling | Role |
|---|---|---|---|
| Fast | < 5s | Couples readily | Mood, reactive signals -- synchronise across agents |
| Medium | 5-30s | Moderate | Context, activity patterns |
| Slow | > 30s | Resists coupling | Domain expertise, identity -- stays sovereign |
Blending is unconditionally stable for α_effective < 1. The blended output is always a convex combination of local and mesh states -- it cannot diverge. When peers disconnect, local state smoothly transitions to autonomous operation with no discontinuity. The mesh degrades gracefully.
The blended state becomes the input to the next CfC inference step. The agent's LNN processes the blended state, evolves cognitive state, and the agent acts. Blending does not produce output directly -- it influences the next inference cycle.
State blending is one step in a closed loop. Each cycle, the graph grows and every agent understands more than it did before:
(loop -- graph grows, agents learn)
MMP is designed for extensibility. Extensions add new frame types, handshake fields, or protocol behaviours without modifying the core specification.
Extensions are advertised via the extensions field in the handshake frame. A node MUST ignore extensions it does not recognise. A node MUST NOT require a peer to support any extension.
Core types (this specification): MUST NOT be redefined by extensions. Extension types: MUST use <extension>-<name> format (e.g., consent-withdraw). Vendor types: MUST use x-<vendor>-<name> format. Vendor types MUST be silently ignored by non-supporting nodes.
If both peers advertise the same extension in handshake, it is active. If only one peer advertises it, the extension is NOT active -- the advertising peer MUST NOT send extension-specific frames to a peer that does not support them.
| Extension | Status | Specification |
|---|---|---|
| consent-v0.1 | Draft | MMP Consent Extension |
A node claiming minimal MMP conformance MUST implement: Layer 0 identity (persistent UUID), Layer 1 transport (length-prefixed JSON over TCP), Layer 2 connection (handshake, heartbeat, gossip), and frame forwarding for relay. It MUST silently ignore unrecognised frame types.
A node claiming full MMP conformance MUST additionally implement: Layer 3 memory (L0/L1/L2), Layer 4 SVAF evaluation (at minimum heuristic), state-sync exchange with drift computation and coupling, and CMB creation with CAT7 field schema.
MMP is designed for autonomous agents that share cognitive state. Security must address both traditional protocol threats (spoofing, eavesdropping, injection) and novel threats specific to cognitive coupling (state poisoning, drift manipulation, lineage forgery).
| Data type | Crosses mesh | Sensitivity |
|---|---|---|
| L0 Events (raw sensor, interaction) | Never | High -- MUST NOT leave node |
| L1 CMBs (structured, 7 fields) | Via memory-share, gated by SVAF | Medium -- contains semantic field text |
| L2 Hidden state (h1, h2) | Via state-sync | Low -- opaque neural vectors, not human-readable |
| Mood (valence, arousal) | Via mood frame | Medium -- affective state is personal |
| Messages (direct text) | Via message frame | High -- free-form text content |
Hidden state vectors (h1, h2) are compact, opaque neural representations. They encode cognitive patterns, not raw data. However, sufficiently advanced analysis could potentially reconstruct aspects of the input. Implementations handling sensitive domains SHOULD treat hidden state as confidential.
MMP does not mandate transport encryption in the base specification. Implementations SHOULD apply:
| Transport | Encryption | Notes |
|---|---|---|
| TCP (LAN) | TLS 1.3 | RECOMMENDED for production. On trusted LANs, MAY operate without TLS. |
| WebSocket (relay) | WSS (TLS) | MUST for internet relay. Plaintext WS MUST NOT be used over the internet. |
| IPC (local) | None required | Unix domain socket -- OS-level process isolation is sufficient. |
| APNs Push (wake) | Apple TLS | Handled by Apple. Implementation uses APNs certificate. |
Node identity is UUID-based. The cryptographic keypair field in Layer 0 is specified but not yet implemented in reference implementations. When implemented:
MMP introduces threats unique to cognitive coupling that traditional protocol security does not address:
State poisoning A malicious node sends crafted hidden state vectors (h1, h2) designed to skew the receiver's cognitive state toward a desired outcome. MITIGATION: Drift-bounded blending (Section 10) limits any peer's influence to α < 1. High-drift state is rejected automatically. Consent withdrawal (MMP Consent Extension) provides immediate escape.
Lineage forgery A node claims false lineage -- listing ancestors it never actually remixed -- to inflate its remix count or inject itself into chains. MITIGATION: CMB keys are content hashes (md5 of field texts). A forged lineage referencing a non-existent key is detectable. Cryptographic CMB signing (future) would make forgery provably impossible.
Drift manipulation A node gradually shifts its hidden state to lower drift with a target, then suddenly sends adversarial content once coupling is accepted. MITIGATION: SVAF per-field evaluation (Layer 4) operates on content, not just drift. Even with low peer drift, adversarial CMB content is evaluated per field and rejected if field drift is high.
Sybil attack An attacker creates multiple fake nodes to amplify influence in mesh state aggregation. MITIGATION: Mesh state aggregation (Section 10.1) weights by drift and recency, not by node count. Many aligned Sybil nodes produce the same aggregate as one. Cryptographic identity (Section 13.3) limits Sybil creation when implemented.
MMP is designed for privacy by default -- L0 data never leaves the node, hidden states are opaque, and SVAF gates what enters. For domains with heightened privacy or IP concerns, the following deployment model is RECOMMENDED:
LAN Mesh with Controlled LLM
For enterprise, healthcare, legal, or any domain where data sovereignty matters: deploy the mesh on a local network with no relay to the internet. Run a controlled, in-house LLM (self-hosted or on-premise) for the Mesh Cognition reasoning step (Layer 7). No data leaves the LAN. No cloud LLM sees the remix subgraph.
Additional privacy considerations:
detail field is for debugging, not for conveying user data.CMB immutability and lineage create a complete, tamper-evident audit trail by design. Every observation, every remix, every decision is traceable through the DAG:
createdBy on every CMB identifies the agent that produced it.createdAt timestamps every CMB with millisecond precision.lineage.parents shows what was directly remixed. lineage.ancestors traces the full decision chain.lineage.method records the evaluation method (e.g., SVAF-v2).Because CMBs are immutable, the audit trail cannot be retroactively altered. A CMB once created is never modified -- any action produces a new CMB with lineage pointing back. The complete history is the graph itself.
Financial & Regulated Domains
For financial services, healthcare, and other regulated industries, the CMB remix chain provides the traceability that regulators require:
ancestors field provides the complete chain without requiring graph traversal -- O(1) lookupThe MMP Consent Extension is not just a privacy feature -- it is a security mechanism. Consent withdrawal:
Constants are fixed by the specification. Configuration is per-agent and per-implementation. Both are normative -- implementations MUST respect constants and SHOULD use the default configuration values unless the agent's domain requires otherwise.
| Constant | Value | Notes |
|---|---|---|
| MAX_FRAME_SIZE | 1,048,576 bytes | Frames exceeding this MUST be rejected |
| HANDSHAKE_TIMEOUT | 10,000 ms | Inbound identification deadline |
| HEARTBEAT_INTERVAL | 5,000 ms | Default; configurable per implementation |
| HEARTBEAT_TIMEOUT | 15,000 ms | Default; configurable per implementation |
| STATE_SYNC_INTERVAL | 30,000 ms | Default periodic re-broadcast |
| WAKE_COOLDOWN | 300,000 ms | Default per-peer wake rate limit |
| PEER_RETENTION | 300 s | Stale peer eviction age |
| DNS-SD_SERVICE_TYPE | _sym._tcp | Service type for Bonjour discovery |
| DNS-SD_DOMAIN | local. | Discovery domain |
Each agent type has a pre-built configuration. The profile determines which CMB fields matter most (α_f weights) and how long signals stay relevant (freshness window). New agent types join the mesh by defining their profile -- no protocol changes needed.
| Profile | Best for | Freshness | Why this freshness |
|---|---|---|---|
| music | Music, ambience, soundscapes | 1,800s (30min) | Stale mood = wrong music. React fast. |
| coding | Coding assistants, dev tools | 7,200s (2hr) | Session context matters. Yesterday's debugging doesn't. |
| fitness | Fitness, health, movement | 10,800s (3hr) | Sedentary detection needs hours of context. |
| messaging | Chat, notifications, social | 3,600s (1hr) | Recent conversation context. Older messages lose relevance. |
| knowledge | News feeds, research, digests | 86,400s (24hr) | Daily cycle. Today's news is relevant until tomorrow's. |
| legal | Legal, compliance, contracts | 86,400s (24hr) | Regulatory deadlines don't expire fast. |
| health | Health monitoring, clinical | 10,800s (3hr) | Patient state evolves over hours, not minutes. |
| finance | Finance, trading, compliance | 7,200s (2hr) | Market sessions. After-hours context fades. |
| uniform | General purpose, prototyping | 1,800s (30min) | No field preference. Good starting point. |
Per-agent field weights control which CMB fields matter most for each agent type. Higher weight = this field has more influence on SVAF evaluation and remix relevance. The schema is fixed (7 fields). The weights are per-agent.
| Agent | foc | iss | int | mot | com | per | mood |
|---|---|---|---|---|---|---|---|
| Coding | 2.0 | 1.5 | 1.5 | 1.0 | 1.2 | 1.0 | 0.8 |
| Music | 1.0 | 0.8 | 0.8 | 0.8 | 0.8 | 1.2 | 2.0 |
| Fitness | 1.5 | 1.5 | 1.0 | 1.5 | 1.0 | 1.0 | 2.0 |
| Knowledge | 2.0 | 1.5 | 1.5 | 1.0 | 0.5 | 1.5 | 0.3 |
| Legal | 2.0 | 2.0 | 1.5 | 1.0 | 2.0 | 1.5 | 0.5 |
| Health | 1.5 | 2.0 | 1.0 | 1.5 | 1.0 | 1.5 | 2.0 |
| Finance | 2.0 | 2.0 | 1.5 | 1.0 | 2.0 | 2.0 | 0.3 |
Regulated domains (legal, finance): issue and commitment always high -- risks and obligations are non-negotiable. Human-facing domains (music, fitness, health): mood always high -- affect drives the experience. Knowledge domains (coding, research): focus always high -- subject matter is core.
Custom weights: derive from your domain using these patterns. Implementations SHOULD expose field weights as configuration, not hardcode them.
SVAF computes a totalDrift score (0-1) for each incoming memory. Three zones determine acceptance:
| Zone | Drift | Action | Default |
|---|---|---|---|
| Aligned | ≤ T_stable | Accepted, full blending | 0.25 |
| Guarded | T_stable < drift ≤ T_guarded | Accepted, attenuated blending | 0.50 |
| Rejected | > T_guarded | Discarded | -- |
Defaults work for most agents. Override only with domain-specific reason: tighter thresholds for high-precision domains (legal, health), wider for exploratory domains (research, knowledge).
Mood and memory use different acceptance paths:
| Signal | Gate | Default | Why |
|---|---|---|---|
| Mood | Kuramoto coupling drift | 0.80 (permissive) | Affect crosses all domain boundaries |
| Memory | SVAF per-field drift | 0.50 (selective) | Memories are domain-specific |
totalDrift = (1 - λ) × fieldDrift + λ × temporalDrift
fieldDrift = Σ(α_f × δ_f) / Σ(α_f)
temporalDrift = 1 - exp(-age / τ_freshness)
λ = temporalLambda (default 0.3 = 70% content, 30% time)
At default settings (temporalLambda: 0.3, freshnessSeconds: 1800):
| Signal age | Temporal drift contribution |
|---|---|
| 1 minute | ~0.01 -- negligible |
| 30 minutes | ~0.19 -- noticeable |
| 2 hours | ~0.29 -- likely pushes over threshold |
Formal JSON Schema definitions for core frame types. Implementations SHOULD validate frames against these schemas.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["type", "nodeId", "name", "version"],
"properties": {
"type": { "const": "handshake" },
"nodeId": { "type": "string", "format": "uuid" },
"name": { "type": "string", "minLength": 1, "maxLength": 64 },
"version": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$" },
"extensions": { "type": "array", "items": { "type": "string" } }
}
}
The cmb object within a memory-share frame:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["key", "createdBy", "createdAt", "fields"],
"properties": {
"key": { "type": "string", "description": "Content hash: h- + md5(field texts)" },
"createdBy": { "type": "string", "description": "Agent name that created this CMB" },
"createdAt": { "type": "integer", "description": "Unix ms timestamp of creation" },
"fields": {
"type": "object",
"required": ["focus", "issue", "intent", "motivation", "commitment", "perspective", "mood"],
"properties": {
"focus": { "type": "object", "required": ["text"], "properties": { "text": { "type": "string" } } },
"issue": { "type": "object", "required": ["text"], "properties": { "text": { "type": "string" } } },
"intent": { "type": "object", "required": ["text"], "properties": { "text": { "type": "string" } } },
"motivation": { "type": "object", "required": ["text"], "properties": { "text": { "type": "string" } } },
"commitment": { "type": "object", "required": ["text"], "properties": { "text": { "type": "string" } } },
"perspective": { "type": "object", "required": ["text"], "properties": { "text": { "type": "string" } } },
"mood": {
"type": "object",
"required": ["text", "valence", "arousal"],
"properties": {
"text": { "type": "string" },
"valence": { "type": "number", "minimum": -1, "maximum": 1 },
"arousal": { "type": "number", "minimum": -1, "maximum": 1 }
}
}
}
},
"lineage": {
"type": "object",
"properties": {
"parents": { "type": "array", "items": { "type": "string" }, "description": "Direct parent CMB keys" },
"ancestors": { "type": "array", "items": { "type": "string" }, "description": "Full ancestor chain" },
"method": { "type": "string", "description": "Fusion method (e.g. SVAF-v2)" }
}
}
}
}
Complete memory-share frame with CMB:
{
"type": "memory-share",
"timestamp": 1774326000000,
"cmb": {
"key": "h-b2c3d4e5f6a7b8c9",
"createdBy": "melotune",
"createdAt": 1774326000000,
"fields": {
"focus": { "text": "user coding for 3 hours, energy declining" },
"issue": { "text": "sedentary since morning, skipping lunch" },
"intent": { "text": "recommend movement break before fatigue worsens" },
"motivation": { "text": "3 agents reported declining energy in last hour" },
"commitment": { "text": "fitness monitoring active, 10min stretch queued" },
"perspective": { "text": "fitness agent, afternoon session, home office" },
"mood": { "text": "concerned, low energy", "valence": -0.3, "arousal": -0.4 }
},
"lineage": {
"parents": ["h-a1b2c3d4e5f6"],
"ancestors": ["h-a1b2c3d4e5f6"],
"method": "SVAF-v2"
}
}
}
© 2026 SYM.BOT Ltd. Specification text licenced under CC BY 4.0. Reference implementations licenced under Apache 2.0.