7. Frame Types — MMP Specification

7. Frame Types

All frames are JSON objects with a type field (string). Implementations MUST silently ignore frames with unrecognised type values to allow forward compatibility.

7.1 Frame Type Registry

The table is rendered from the normative machine-readable frame registry; its own shape is validated by frame-registry.schema.json.

Type Layer Gated Status Schema Fields
client-hello 2 No core handshake.schema.json First authenticated handshake offer.
server-hello 2 No core handshake.schema.json Server offer, negotiated extensions, transcript proof and key confirmation.
client-finish 2 No core handshake.schema.json Transcript hash, client proof and key confirmation.
cmb 3/4 SVAF core cmb-frame.schema.json Signed CAT7 record assertion.
cmb-encrypted 2/3 After decrypt core encrypted-cmb-frame.schema.json Directional ChaCha20-Poly1305 envelope with session, sequence, routing metadata and sealed record bytes.
cmb-fetch 3 No core cmb-fetch.schema.json Request a record by exact content address.
cmb-fetch-result 3 No core cmb-fetch-result.schema.json Self-verifying result for an exact content-address request.
role-grant 3 Authority core authority-frame.schema.json Signed, anchor-rooted lifecycle role grant.
role-revoke 3 Authority core authority-frame.schema.json Signed revocation of a lifecycle role grant.
peer-info 2 No core control-frame.schema.json Authenticated-room peer and wake-channel gossip.
wake-channel 2 No core control-frame.schema.json Platform wake-channel registration.
error 2 No core control-frame.schema.json Protocol error code, message and optional bounded detail.
ping 2 No core control-frame.schema.json Peer keepalive request.
pong 2 No core control-frame.schema.json Peer keepalive response.
relay-auth 1 Relay auth transport relay-frame.schema.json Authenticate a node to a relay.
relay-peers 1 No transport relay-frame.schema.json Relay peer directory.
relay-ping 1 No transport relay-frame.schema.json Relay keepalive request.
relay-pong 1 No transport relay-frame.schema.json Relay keepalive response.
relay-reauth 1 No transport relay-frame.schema.json Request a fresh relay-auth frame.
relay-peer-joined 1 No transport relay-frame.schema.json Relay presence notification.
relay-peer-left 1 No transport relay-frame.schema.json Relay departure notification.
relay-error 1 No transport relay-frame.schema.json Relay-level error.
state-sync deprecated No legacy Reserved legacy type. MUST NOT emit; ignore on receipt.
message legacy No legacy Legacy unsigned application message.
mood legacy No legacy Legacy mood fast path; Core Secure carries mood inside CAT7.
xmesh-insight legacy No legacy Legacy runtime projection.

All cognitive content — observations, decisions, feedback, directives — MUST be sent as cmb frames. Only cmb frames enter SVAF evaluation, produce anchor weights, and modulate CfC state.

The registry distinguishes Core Secure wire types from retained legacy and runtime-extension types. A Core Secure participant MUST complete the three-frame authenticated handshake before it accepts cmb or cmb-encrypted. It MUST NOT silently downgrade to the legacy one-frame handshake or to an unsigned application frame.

The relay-* types are transport-scope (Section 4.4): they are exchanged between a node and a relay, never between peers, and never reach the application layer. The relay forwards peer frames as opaque payloads (Section 4.4.4) and does not originate any of the peer-scope types above.

Deprecated — state-sync. The state-sync frame carried a node’s hidden-state vectors (h₁, h₂). Per the hidden-state locality invariant (Section 2.7), hidden state MUST NOT cross the wire. Implementations MUST NOT emit state-sync and SHOULD ignore it on receipt. It is retained in this registry only to reserve the type and document the deprecation; all peer influence flows through cmb frames evaluated by SVAF.

7.2 Error Frame

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.

CodeNameActionDescription
1001 VERSION_MISMATCH Close Peer version is incompatible
1002 DIMENSION_MISMATCH Reject frame Vector dimension mismatch (legacy state-sync; deprecated — see §2.7)
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)
1006 AUTHENTICATION_FAILED Close Transcript signature or key confirmation failed
1007 ROOM_MISMATCH Close Authenticated room does not match the local room
1008 REPLAY_DETECTED Close Encrypted-frame counter repeated or moved backwards

Codes 1xxx are connection-level (close connection). Codes 2xxx are evaluation-level (informational). Error frames MUST NOT contain sensitive information.

7.3 Type Naming and Extensions

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.

Q&A

Why MUST nodes silently ignore unknown frame types?

Without this rule, you can never add new features to the protocol. If a node crashes or rejects unknown frame types, then deploying a new extension (like mesh rooms) requires upgrading every node on the mesh simultaneously — impossible in a peer-to-peer system. Silent ignore means old nodes and new nodes coexist: a node running a new extension sends its frames, and nodes that don’t support the extension simply ignore them. No crash, no error, the mesh keeps working. When a node adds support later, it handles the frame. No coordinated upgrade needed. This is the same principle used by HTTP (unknown headers ignored), TCP (unknown options skipped), and HTML (unknown tags ignored). Every successful protocol is evolvable because of this rule.

What happens if a relay receives an unknown frame type?

The relay forwards it. The relay is a dumb transport pipe — it wraps the payload in a { from, fromName, payload } envelope and sends it to the target or broadcasts it. It never inspects the payload type. This means extension frames (room, vendor, future types) flow through the relay without any relay changes. The intelligence is at the endpoints, not the transport.

Can an extension frame break an existing node?

No, if the node follows Section 7. The frame handler switches on msg.type. Unknown types fall through with no match and no action. The node’s cognitive state, memory, and coupling are unaffected. This is a hard requirement — implementations that reject or error on unknown types are non-conformant.