Skip to content

XProtocol — The Exchange Protocol: Full Specification

Protocol Version: 0.2 (Draft) Date: 2026-05-31 License: CC BY 4.0 (this document) · Apache 2.0 (code) Status: Draft — reference implementation forthcoming

The universal AI exchange protocol — full technical specification.

Identity belongs to the user. Interoperability belongs to the ecosystem. Intelligence belongs to agents.

What if the internet had been designed assuming software agents were the primary consumers instead of humans?


License

XProtocol is free and open. Code is licensed under Apache 2.0. Documentation and specifications (including this document) are licensed under CC BY 4.0. See LICENSE and LICENSE-DOCS in the repository root.

Apache 2.0's Section 3 includes an explicit patent license grant — every contributor automatically licenses any relevant patent claims to all users of the project, royalty-free and irrevocably. XProtocol is unencumbered. Build on it freely.


Core Protocol vs. Ecosystem Extensions

XProtocol has a small, complete core. Everything else is optional.

┌─────────────────────────────────────────────────────────┐
│  XProtocol Core — six primitives, complete on its own   │
│                                                         │
│  1. Cryptographic identity (Ed25519 + X25519 keypairs)  │
│  2. Signed, encrypted events                            │
│  3. Schema contracts                                    │
│  4. Pluggable discovery & transport (relay mandatory)   │
│  5. Request-response semantics                          │
│  6. Standard error codes                                │
│                                                         │
│  A SaaS vendor can publish a conformant XProtocol       │
│  endpoint in a day using only these six primitives.     │
│  A minimal conformant implementation is complete.       │
└─────────────────────────────────────────────────────────┘
          │ optionally extended by
┌─────────────────────────────────────────────────────────┐
│  XProtocol Ecosystem Extensions — adopt as needed       │
│                                                         │
│  • Event Store — persistent queryable event history     │
│  • Graph Store — mutable annotation & relationship layer│
│  • Environment Model — cryptographic env management     │
│  • Workflow — process state on events                   │
│  • Agent Memory — AI semantic annotation layer          │
│  • Discovery extensions — UWB, visual, audio, proximity │
│  • Identity Wallet — key management & recovery UI       │
└─────────────────────────────────────────────────────────┘

Implementations that support only the core are fully conformant. Extensions are additive, not required. Every section of this document that covers an extension is marked [OPTIONAL EXTENSION].


For the Non-Technical Reader

Every time you use a piece of software that talks to another piece of software — your phone checking email, your CRM syncing with your accounting tool, your AI assistant booking a restaurant — there is an invisible stack of complexity making it work. Authentication tokens, API keys, OAuth flows, webhook callbacks, JSON payloads, rate limits, versioned endpoints, integration middleware. Billions of dollars and millions of engineering hours are spent every year building, maintaining, and debugging these connections.

And every time you message a friend, you navigate a parallel fragmentation — iMessage for some contacts, WhatsApp for others, Signal for a few, SMS as a fallback. Each platform silos your identity, your conversations, and your contacts. Switching costs keep you locked in.

The XProtocol replaces all of it — both the service integration stack and the communication fragmentation — with one idea: every interaction between any two parties is a signed, encrypted event. Your cryptographic identity IS your login, your phone number, and your social account. Your signature IS your authentication. The event IS the API call, the message, the post, the query. One protocol for messaging a friend, querying your CRM, booking a restaurant, and posting to your feed.

For a business, this means: connecting to a new vendor is as simple as exchanging public keys. No IT project. No integration middleware. No months-long onboarding. Your AI agent learns the vendor's event schema and starts interacting immediately.

For a vendor, this means: publishing your service on XProtocol makes you instantly accessible to every AI agent and every Explan device in the world. No app to build. No API documentation portal to maintain. No developer relations team to hire. You publish your schema, and the world can use your service.

For the industry, this means: the era of proprietary APIs as competitive moats is over. Services compete on quality, not on lock-in.


The Problem with Current Service Integration

REST APIs — The Standard That Isn't Standard

REST is the dominant paradigm for service-to-service communication. It is also, after twenty years, a mess.

Every vendor implements REST differently. Salesforce's REST API bears no structural resemblance to Stripe's, which bears no resemblance to Twilio's. Endpoint naming conventions, pagination strategies, error formats, authentication mechanisms, rate limiting approaches, versioning schemes — all different. "REST" provides a transport mechanism (HTTP verbs on URLs) and nothing else. Everything above the transport is bespoke.

The result: connecting to a new vendor requires reading hundreds of pages of documentation, writing custom integration code, handling vendor-specific authentication flows, managing API keys, building retry logic, parsing vendor-specific error responses, and maintaining all of it as the vendor changes their API. This is repeated for every vendor, by every customer, millions of times across the industry.

OAuth — Authentication Theater

OAuth 2.0 was designed to solve a real problem: letting users grant third-party applications limited access to their accounts without sharing passwords. It has become a Byzantine labyrinth of grant types, token types, scopes, redirect URIs, PKCE challenges, client secrets, refresh token rotation, and token introspection endpoints.

A typical OAuth integration requires: registering an application with the vendor, obtaining client credentials, implementing the authorization code flow (or device flow, or client credentials flow, depending on the use case), handling token refresh, managing token storage, handling token revocation, and dealing with vendor-specific OAuth extensions. This process takes days to weeks per vendor.

The fundamental issue: OAuth separates identity from the protocol. You authenticate through OAuth, then use REST. Two systems, loosely coupled, each with their own failure modes.

MCP — Validating the Need

Anthropic's Model Context Protocol (MCP) correctly identifies that AI agents need a standardized way to discover and invoke services. MCP defines a protocol for tool discovery, invocation, and response — and it works. It has demonstrated that AI agents can interact with arbitrary services through a structured protocol rather than custom integration code.

XProtocol builds on MCP's validated insight and pushes it deeper into the stack. Where MCP provides tool discovery and invocation over HTTP/SSE transport, XProtocol embeds identity, authentication, encryption, and schema-native validation directly into the protocol. Where MCP defines tools at the server level (each server declares its own tools), XProtocol defines operations through a universal schema contract that AI agents can compile into generation grammars. MCP is the right idea at the application layer; XProtocol is the same idea pushed down into the identity and transport layers.

The two are not incompatible — they are bridged by the XProtocol MCP Adapter, a universal bidirectional bridge:

  • MCP → XProtocol: Any existing MCP server becomes an XProtocol endpoint automatically. The adapter reads the MCP server's tool definitions, generates XProtocol schema contracts, compiles GBNF grammars, and presents the server as a signed XProtocol endpoint — with no changes to the MCP server.
  • XProtocol → MCP: Any XProtocol endpoint becomes an MCP tool set automatically. Claude Code, Claude Desktop, or any MCP client can call any XProtocol-native service without knowing anything about XProtocol.

Configuration requires a YAML file — no code, no SDK integration, no schema authoring. Organizations that have invested in MCP adopt XProtocol in minutes with zero disruption to existing systems.

Full specification: XProtocol-MCP-Adapter-Spec.md

Webhooks — The Fragile Callback

When a vendor needs to notify you of an event (a payment completed, a record changed, a message received), they use webhooks — HTTP POST requests to a URL you provide. This requires: a publicly accessible endpoint, signature verification, retry handling, idempotency management, and failure recovery. Webhooks are inherently fragile (what if your endpoint is down?), insecure (spoofed callbacks are a constant threat), and unauditable (no cryptographic proof of delivery).

The Integration Tax

The cumulative cost of this fragmentation is staggering. Enterprises spend 30-40% of their IT budgets on integration. Companies like MuleSoft, Zapier, Workato, and Boomi exist solely to bridge the gap between incompatible APIs. Every SaaS vendor maintains a developer relations team, an API documentation portal, SDKs in multiple languages, and OAuth application management infrastructure. All of this is overhead — none of it delivers value to the end user.


The XProtocol

XProtocol is a universal protocol for all service interactions built on three primitives: cryptographic identity, signed events, and service endpoints.

Design Principles

  1. Identity is the protocol. There is no separate authentication layer. The cryptographic keypair that identifies the sender IS the authentication mechanism. Every event is signed. Every signature is verifiable. No tokens, no sessions, no credentials to manage.

  2. One protocol for everything. Queries, mutations, subscriptions, file transfers, streaming data, batch operations — all expressed as events within the same protocol. No REST for queries, WebSockets for real-time, SFTP for files, and webhooks for callbacks. One protocol.

  3. Schema is the API. Services publish their event schema. The schema defines what operations are available, what data they accept, and what they return. There is no separate API documentation, no SDK, no endpoint reference. The schema IS the complete API surface.

  4. Encryption by default. All events are encrypted to the recipient's public key. The service endpoint sees ciphertext in transit. Only the intended recipient can read the payload. End-to-end encryption is not a feature — it is the transport mechanism.

  5. Audit is inherent. Every event is signed and timestamped. The complete history of interactions between any two parties is a chain of cryptographically verifiable events. No separate audit logging system required.

  6. AI-native. The protocol is designed to be composed by AI agents, not hand-coded by developers. An AI agent reads a service's schema, understands the available operations, and composes events. No integration code. No SDK. The AI IS the integration layer.


Protocol Architecture

Identity

Every participant in XProtocol — a person, a company, an AI agent, a service — has an Ed25519 keypair.

  • Public key: The identifier. This is how you are known to the network. Analogous to a Nostr npub, but used for all service interactions, not just social messaging.
  • Private key: The signer. Never transmitted. Used to sign events and decrypt incoming messages. Stored in the device's secure enclave (for individuals) or HSM (for services).

There are no usernames, no email addresses, no account IDs at the protocol level. A public key IS the identity. Derived identifiers (human-readable names, organizational mappings) are metadata associated with keys, not protocol primitives.

Key Hierarchies

Organizations use hierarchical key structures:

Organization Root Key
├── Department Key (Engineering)
│   ├── Employee Key (Alice)
│   ├── Employee Key (Bob)
│   └── Service Account Key (CI/CD Pipeline)
├── Department Key (Sales)
│   ├── Employee Key (Carol)
│   └── Employee Key (Dave)
└── System Key (Internal Services)
    ├── CRM Integration Key
    └── Billing Integration Key

The organization root key signs department keys. Department keys sign employee keys. This creates a verifiable chain of authority: "Alice is authorized to act on behalf of Engineering, which is a department of Acme Corp." Any service can verify this chain by walking the signatures up to the root key.

Key revocation is an event: the parent key publishes a revocation event for the child key. All services monitoring revocation feeds immediately stop accepting events from the revoked key.

Events

The fundamental unit of communication in XProtocol is the event. Every interaction — a query, a command, a notification, a response — is an event.

Event Structure

{
  "id": "sha256-hash-of-serialized-content",
  "sender": "ed25519-public-key-of-sender",
  "recipient": "ed25519-public-key-of-recipient",
  "endpoint": "ed25519-public-key-of-service-endpoint",
  "kind": "namespace.entity.operation",
  "correlation_id": "uuid-linking-request-to-response",
  "timestamp": 1717000000,
  "expires": 1717003600,
  "schema_version": "1.0.0",
  "payload": { ... },
  "signature": "ed25519-signature-of-id"
}

Field Definitions

Field Type Description
id string SHA-256 hash of the serialized event content (excluding id and signature). Unique, deterministic, content-addressable.
sender string Public key of the event author. Every event has exactly one sender.
recipient string Public key of the intended recipient. The payload is encrypted to this key.
endpoint string Public key of the service endpoint processing this event. May differ from recipient in multi-party scenarios.
kind string Dot-notation operation identifier. Namespace is the vendor, entity is the data type, operation is the action. Example: salesforce.opportunity.create, stripe.payment.charge, acme.inventory.query.
correlation_id string UUID that links a request event to its response event. The response carries the same correlation_id as the request. This is how request-response semantics work over an asynchronous event protocol.
timestamp integer Unix timestamp of event creation. Signed as part of the event content, so it cannot be tampered with.
expires integer Unix timestamp after which the event should not be processed. Prevents replay attacks and stale request processing.
schema_version string Semantic version of the event schema this event conforms to. Enables backward-compatible evolution.
payload object The operation-specific data. Encrypted to the recipient's public key. Structure defined by the service's published schema for this event kind.
signature string Ed25519 signature of the event id using the sender's private key. Proves authorship and integrity.

Event Kinds — The Universal API

Event kinds follow a hierarchical naming convention:

{vendor}.{entity}.{operation}

Examples:
  salesforce.opportunity.create
  salesforce.opportunity.query
  salesforce.opportunity.update
  salesforce.opportunity.delete
  salesforce.opportunity.subscribe

  stripe.payment.charge
  stripe.payment.refund
  stripe.subscription.create

  acme-corp.inventory.check
  acme-corp.order.place
  acme-corp.order.status

Standard operations are defined at the protocol level:

Operation suffix Semantics
.create Create a new entity. Request contains entity data. Response contains the created entity with server-assigned fields (ID, timestamps).
.read Read a single entity by ID. Request contains the entity ID. Response contains the full entity.
.update Update an existing entity. Request contains entity ID and fields to change. Response contains the updated entity.
.delete Delete an entity. Request contains entity ID. Response confirms deletion.
.query Query entities with filters, sorting, and pagination. Request contains query parameters. Response contains matching entities.
.subscribe Subscribe to real-time changes. Request contains filter criteria. Service publishes change events as they occur.
.unsubscribe Cancel a subscription.
.batch Batch multiple operations in a single event. Request contains an array of operations. Response contains an array of results.
.schema Request the schema definition for this entity. Response contains the full schema.

Vendors can define custom operations beyond the standard set:

salesforce.opportunity.convert-to-order
stripe.payment.capture-authorization
acme-corp.inventory.reserve

Service Endpoints

A service endpoint is the XProtocol equivalent of a server. It is identified by its public key and reachable via a well-known URL.

Endpoint Discovery

Services publish their endpoint information as a discoverable event:

{
  "kind": "xp.endpoint.announce",
  "payload": {
    "name": "Salesforce CRM",
    "description": "Customer relationship management platform",
    "url": "wss://xp.salesforce.com/v1",
    "transport": ["websocket", "https-post"],
    "public_key": "endpoint-ed25519-public-key",
    "schema_url": "https://xp.salesforce.com/schema",
    "capabilities": [
      "salesforce.opportunity.*",
      "salesforce.account.*",
      "salesforce.contact.*",
      "salesforce.lead.*"
    ],
    "rate_limits": {
      "requests_per_minute": 1000,
      "burst": 50
    },
    "pricing": {
      "model": "per-seat",
      "seat_definition": "unique-sender-key-per-month"
    }
  }
}

AI agents discover services by querying endpoint directories (analogous to DNS for XProtocol) or by receiving endpoint announcements from the network.

Transport

XProtocol is transport-agnostic. The event structure is the protocol; the transport is just plumbing. Supported transports:

  • WebSocket (primary): Persistent bidirectional connection. Lowest latency. Supports streaming responses and real-time subscriptions. URL format: wss://esp.vendor.com/v1
  • HTTPS POST (fallback): Stateless request-response. Higher latency but works everywhere, including through corporate proxies. URL format: https://esp.vendor.com/v1/events
  • Relay-mediated: For offline-first scenarios. Events are published to a relay (Nostr-compatible) and the service endpoint subscribes. Higher latency but supports disconnected operation.

The sender publishes an event. The transport delivers it. The recipient processes it and publishes a response event with the same correlation_id. The sender receives the response. The transport is invisible to the application logic.


Request-Response Semantics

Unlike pure pub-sub protocols (including Nostr), XProtocol has first-class request-response semantics built on top of the event model.

Synchronous Request-Response

Sender                           Service Endpoint
  |                                     |
  |  Event (kind: x.entity.read)        |
  |  correlation_id: abc-123            |
  | ----------------------------------> |
  |                                     |  (process)
  |  Event (kind: x.entity.read.result) |
  |  correlation_id: abc-123            |
  | <---------------------------------- |
  |                                     |

The sender publishes a request event and waits for a response event with the matching correlation_id. Timeout is defined by the expires field on the request. If no response arrives before expiry, the sender treats it as a failure.

Asynchronous Request-Response

For long-running operations (report generation, batch processing, AI inference):

Sender                           Service Endpoint
  |                                     |
  |  Event (kind: x.report.generate)    |
  |  correlation_id: abc-123            |
  | ----------------------------------> |
  |                                     |
  |  Event (kind: xp.ack)              |
  |  correlation_id: abc-123            |
  |  status: "accepted"                 |
  |  estimated_completion: 1717002000   |
  | <---------------------------------- |
  |                                     |  (processing...)
  |                                     |
  |  Event (kind: x.report.generate.progress) |
  |  correlation_id: abc-123            |
  |  progress: 0.45                     |
  | <---------------------------------- |
  |                                     |  (processing...)
  |                                     |
  |  Event (kind: x.report.generate.result) |
  |  correlation_id: abc-123            |
  |  payload: { report_data }           |
  | <---------------------------------- |
  |                                     |

The service immediately acknowledges receipt (xp.ack), optionally sends progress events, and publishes the final result when ready. The sender's AI agent can tell the user "Your report is being generated, about 45% done" based on the progress events.

Streaming Responses

For operations that return large or incremental datasets:

Sender                           Service Endpoint
  |                                     |
  |  Event (kind: x.entity.query)       |
  |  correlation_id: abc-123            |
  |  payload: { filters, page_size: 50 }|
  | ----------------------------------> |
  |                                     |
  |  Event (kind: x.entity.query.chunk) |
  |  correlation_id: abc-123            |
  |  payload: { items: [...50], cursor } |
  | <---------------------------------- |
  |                                     |
  |  Event (kind: x.entity.query.chunk) |
  |  correlation_id: abc-123            |
  |  payload: { items: [...50], cursor } |
  | <---------------------------------- |
  |                                     |
  |  Event (kind: x.entity.query.complete) |
  |  correlation_id: abc-123            |
  |  payload: { total_count: 142 }      |
  | <---------------------------------- |
  |                                     |

Subscriptions (Real-Time)

Sender                           Service Endpoint
  |                                     |
  |  Event (kind: x.entity.subscribe)   |
  |  correlation_id: abc-123            |
  |  payload: { filter: "status=open" } |
  | ----------------------------------> |
  |                                     |
  |  Event (kind: xp.subscription.confirmed) |
  |  correlation_id: abc-123            |
  |  subscription_id: sub-456           |
  | <---------------------------------- |
  |                                     |
  |       ... time passes ...           |
  |                                     |
  |  Event (kind: x.entity.changed)     |
  |  subscription_id: sub-456           |
  |  payload: { entity, change_type }   |
  | <---------------------------------- |
  |                                     |
  |  Event (kind: x.entity.changed)     |
  |  subscription_id: sub-456           |
  |  payload: { entity, change_type }   |
  | <---------------------------------- |
  |                                     |

Subscriptions replace webhooks entirely. No public endpoint required. No callback URL configuration. The service publishes change events to the subscriber's key. The subscriber receives them through their persistent connection (WebSocket) or through a relay.


Structured Queries

XProtocol supports structured queries as first-class events, eliminating the need for GraphQL or vendor-specific query languages.

Query Event Payload

{
  "kind": "salesforce.opportunity.query",
  "payload": {
    "filter": {
      "and": [
        { "field": "amount", "op": "gte", "value": 100000 },
        { "field": "stage", "op": "in", "value": ["Negotiation", "Closed Won"] },
        { "field": "close_date", "op": "between", "value": ["2026-01-01", "2026-06-30"] }
      ]
    },
    "sort": [
      { "field": "amount", "direction": "desc" }
    ],
    "fields": ["id", "name", "amount", "stage", "close_date", "account.name"],
    "page_size": 50,
    "cursor": null
  }
}

Query Operators

Operator Description Example
eq Equals { "field": "status", "op": "eq", "value": "active" }
neq Not equals { "field": "status", "op": "neq", "value": "deleted" }
gt, gte Greater than (or equal) { "field": "amount", "op": "gte", "value": 1000 }
lt, lte Less than (or equal) { "field": "age", "op": "lt", "value": 30 }
in In set { "field": "stage", "op": "in", "value": ["A", "B"] }
nin Not in set { "field": "status", "op": "nin", "value": ["deleted"] }
between Range (inclusive) { "field": "date", "op": "between", "value": ["2026-01-01", "2026-12-31"] }
contains String contains { "field": "name", "op": "contains", "value": "Acme" }
starts_with String prefix { "field": "email", "op": "starts_with", "value": "admin" }
is_null Null check { "field": "deleted_at", "op": "is_null", "value": true }
exists Field exists { "field": "custom_field", "op": "exists", "value": true }

Logical operators and, or, and not can be nested to arbitrary depth.

Relationship Traversal

The fields array supports dot-notation for traversing relationships:

"fields": ["id", "name", "account.name", "account.industry", "owner.email"]

This replaces GraphQL's nested query syntax with a flat, predictable format that AI agents can compose reliably.

Aggregation

{
  "kind": "salesforce.opportunity.query",
  "payload": {
    "aggregate": [
      { "function": "sum", "field": "amount", "as": "total_pipeline" },
      { "function": "count", "as": "deal_count" },
      { "function": "avg", "field": "amount", "as": "average_deal" }
    ],
    "group_by": ["stage"],
    "filter": {
      "field": "close_date", "op": "gte", "value": "2026-01-01"
    }
  }
}

Response:

{
  "kind": "salesforce.opportunity.query.result",
  "payload": {
    "groups": [
      { "stage": "Prospecting", "total_pipeline": 450000, "deal_count": 12, "average_deal": 37500 },
      { "stage": "Negotiation", "total_pipeline": 1200000, "deal_count": 8, "average_deal": 150000 },
      { "stage": "Closed Won", "total_pipeline": 3400000, "deal_count": 22, "average_deal": 154545 }
    ]
  }
}

Query Extensibility & Escape Hatches

The structured query model covers 80% of use cases cleanly. But complex analytics — deeply nested subqueries, window functions, pivot tables, arbitrary computed columns — can push beyond what a structured filter/sort/aggregate model expresses naturally.

XProtocol handles this through query extensions — vendor-declared custom query capabilities:

{
  "kind": "salesforce.opportunity.query",
  "payload": {
    "mode": "advanced",
    "query_language": "soql",
    "raw_query": "SELECT Account.Name, SUM(Amount), CALENDAR_YEAR(CloseDate) FROM Opportunity WHERE Amount > 100000 GROUP BY Account.Name, CALENDAR_YEAR(CloseDate) HAVING SUM(Amount) > 500000 ORDER BY SUM(Amount) DESC"
  }
}

The service's schema declares which query modes it supports:

"query_modes": {
  "structured": { "description": "Standard XProtocol structured queries", "always_available": true },
  "soql": { "description": "Salesforce Object Query Language", "documentation_url": "..." },
  "sql_subset": { "description": "ANSI SQL subset (SELECT, JOIN, GROUP BY, HAVING)", "documentation_url": "..." }
}

The AI agent prefers structured mode (grammar-constrained, guaranteed valid) but falls back to vendor-specific query languages when the structured model can't express the query. The schema tells the agent what's available.

This preserves the "structured by default, flexible when needed" principle — the 80% stays clean and AI-composable, and the 20% has an explicit, schema-declared escape path rather than an undocumented workaround.


Schema Contracts

Services publish their schema as a machine-readable contract. This is the complete API surface — no separate documentation required.

Two-Phase Agent Interaction Model

Schema contracts support two distinct agent interaction phases that must be explicitly designed for. Conflating them is the primary source of agent routing failures.

Phase 1 — Discovery (what's available and when should I use it): The agent scans available schemas and selects the right one for its current intent. This phase is semantic — the agent is matching its intent against what services can do. The relevant fields are semantic (structured intent metadata), description (natural language), and use_when (explicit guidance).

Phase 2 — Execution (how do I call it correctly): The agent constructs a valid event for a schema it has already chosen. This phase is structural — the agent is composing a correct payload. The relevant fields are payload (JSON Schema), gbnf_grammar (constrained generation), auth (capability required), and operations (what actions are available).

Current protocols — including MCP and most REST APIs — only fully specify the execution phase. An agent that has been told which tool to call can call it correctly. An agent that needs to decide which tool to call from a large catalog has only free-text descriptions to work with. XProtocol specifies both phases through the semantic annotation field and the xp.schema.describe event.

Schema Discovery

{
  "kind": "xp.schema.request",
  "payload": {
    "namespace": "salesforce",
    "entity": "opportunity"
  }
}

Response:

{
  "kind": "xp.schema.response",
  "payload": {
    "namespace": "salesforce",
    "entity": "opportunity",
    "version": "2.3.0",
    "fields": {
      "id": { "type": "string", "format": "uuid", "read_only": true },
      "name": { "type": "string", "required": true, "max_length": 255 },
      "amount": { "type": "decimal", "precision": 2, "min": 0 },
      "stage": {
        "type": "enum",
        "values": ["Prospecting", "Qualification", "Proposal", "Negotiation", "Closed Won", "Closed Lost"],
        "required": true
      },
      "close_date": { "type": "date", "format": "YYYY-MM-DD" },
      "account": { "type": "reference", "entity": "salesforce.account", "required": true },
      "owner": { "type": "reference", "entity": "salesforce.user" },
      "probability": { "type": "integer", "min": 0, "max": 100 },
      "description": { "type": "text", "max_length": 32000 },
      "created_at": { "type": "datetime", "read_only": true },
      "updated_at": { "type": "datetime", "read_only": true }
    },
    "operations": {
      "create": { "required_fields": ["name", "stage", "account"], "permissions": ["write"] },
      "read": { "permissions": ["read"] },
      "update": { "permissions": ["write"] },
      "delete": { "permissions": ["admin"] },
      "query": { "permissions": ["read"], "max_page_size": 200 },
      "subscribe": { "permissions": ["read"], "max_subscriptions_per_key": 10 },
      "convert-to-order": { "required_fields": ["id"], "permissions": ["write"], "description": "Convert a Closed Won opportunity into a sales order." }
    },
    "relationships": {
      "account": { "entity": "salesforce.account", "cardinality": "many-to-one" },
      "owner": { "entity": "salesforce.user", "cardinality": "many-to-one" },
      "line_items": { "entity": "salesforce.opportunity_line_item", "cardinality": "one-to-many" },
      "contacts": { "entity": "salesforce.contact", "cardinality": "many-to-many", "through": "salesforce.opportunity_contact_role" }
    }
  }
}

Semantic Annotation Field

Every schema contract carries a semantic field that supports Phase 1 discovery. This field is separate from the structural payload definition — it exists specifically for agent intent matching, not for validation.

{
  "kind": "salesforce.opportunity.get",
  "description": "Retrieve a single opportunity record by ID",
  "semantic": {
    "domain": "sales",
    "intent_verbs": ["retrieve", "get", "fetch", "lookup", "find"],
    "data_subjects": ["opportunity", "deal", "pipeline", "prospect"],
    "use_when": "Agent needs the current state of a specific sales opportunity and has its ID",
    "do_not_use_when": "Agent wants to search for opportunities by criteria — use salesforce.opportunity.query instead",
    "related_schemas": ["salesforce.opportunity.query", "salesforce.opportunity.update"],
    "example_inputs": [
      { "id": "opp-abc123", "fields": ["name", "stage", "amount"] }
    ],
    "example_outputs": [
      { "id": "opp-abc123", "name": "Acme Corp Renewal", "stage": "Negotiation", "amount": 45000 }
    ],
    "typical_preconditions": ["Caller has the opportunity ID", "Caller has read capability"],
    "description_quality_score": 0.92
  },
  "payload": { ... },
  "gbnf_grammar": "..."
}

Semantic field definitions:

Field Type Required Purpose
domain string No Business domain — "sales", "hr", "finance", "engineering", "ops"
intent_verbs string[] Recommended Verbs an agent might use when trying to do this — "retrieve", "create", "list", "search"
data_subjects string[] Recommended Nouns this schema operates on — "opportunity", "invoice", "user"
use_when string Recommended Natural language: when should an agent reach for this schema
do_not_use_when string No Natural language: common misuse cases to avoid — explicit routing guidance
related_schemas string[] No Schema kinds that are semantically related — helps agent navigate a catalog
example_inputs object[] No 1-3 representative example payloads — more useful than field descriptions alone
example_outputs object[] No 1-3 representative response examples
typical_preconditions string[] No What the agent usually needs to have before calling this
description_quality_score float Auto 0.0–1.0 score assigned by the adapter or registry — see §xp.schema.describe

The semantic field is advisory, not enforced. The store does not validate semantic content. Its value is entirely in the quality of what the schema publisher writes. Publishing poor semantic annotations produces a schema that is structurally callable but semantically undiscoverable — the agent can call it if told to, but will not reliably find it on its own.

xp.schema.describe — The Semantic Discovery Event

xp.schema.describe is the Phase 1 discovery verb. It answers the agent's "what's here and why would I use it" question, distinct from the Phase 2 execution verbs that answer "how do I call it."

Request:

{
  "kind": "xp.schema.describe",
  "payload": {
    "query": {
      "intent": "I need to find a sales opportunity and check its current stage",
      "domain": "sales",
      "data_subjects": ["opportunity"],
      "limit": 5
    }
  }
}

Response:

{
  "kind": "xp.schema.describe.result",
  "payload": {
    "matches": [
      {
        "kind": "salesforce.opportunity.get",
        "description": "Retrieve a single opportunity record by ID",
        "semantic": {
          "use_when": "Agent needs the current state of a specific sales opportunity and has its ID",
          "intent_verbs": ["retrieve", "get", "fetch", "lookup"],
          "data_subjects": ["opportunity", "deal"],
          "related_schemas": ["salesforce.opportunity.query"]
        },
        "relevance_score": 0.94,
        "auth": { "required_capability": "salesforce.read" }
      },
      {
        "kind": "salesforce.opportunity.query",
        "description": "Search opportunities by criteria",
        "semantic": {
          "use_when": "Agent wants to find opportunities matching criteria without knowing the ID",
          "intent_verbs": ["search", "find", "list", "filter"],
          "data_subjects": ["opportunity", "pipeline"]
        },
        "relevance_score": 0.81,
        "auth": { "required_capability": "salesforce.read" }
      }
    ],
    "total_schemas_searched": 47,
    "endpoint": "xp://salesforce.example.com"
  }
}

Query parameters:

Field Type Description
intent string Free-text description of what the agent wants to do
domain string Optional domain filter
data_subjects string[] Optional subject filter
intent_verbs string[] Optional verb filter
limit integer Max results to return (default: 10)
min_quality_score float Only return schemas with quality score above threshold

Matching algorithm: The endpoint matches the query against all published schemas using intent_verbs, data_subjects, domain, and free-text similarity against use_when and description. The relevance_score in the response is the endpoint's confidence that this schema matches the agent's intent. Implementations may use any matching strategy — keyword, vector similarity, or LLM-based — as long as higher scores reliably indicate better matches.

Relationship to xp.schema.request: xp.schema.request fetches a specific known schema by name — it is a Phase 2 execution preparation step. xp.schema.describe discovers unknown schemas by intent — it is a Phase 1 discovery step. Both are needed. An agent that already knows it wants salesforce.opportunity.get calls xp.schema.request. An agent that knows it wants "something to do with sales opportunities" calls xp.schema.describe first.

What the Schema Enables

  1. AI agent comprehension. An AI agent reads the schema and immediately understands: what entities exist, what fields they have, what operations are available, what permissions are required, and how entities relate to each other. No documentation reading. No SDK installation. No sample code. The schema IS the complete interface.

  2. Validation at the sender. The AI agent validates events against the schema before sending them. A create event missing a required field is caught locally, not after a round-trip to the server. This is especially important for grammar-constrained LLM output (GBNF) — the schema can be compiled into a generation grammar that makes it impossible for the LLM to produce invalid events.

  3. Intent-based discovery. The semantic field and xp.schema.describe event give agents a reliable path from intent ("I need to update a deal") to the correct schema (crm.opportunity.update) without requiring the agent to already know what schemas exist. This is the Phase 1 → Phase 2 bridge.

  4. Schema evolution. Schema versions follow semantic versioning. Minor versions add optional fields (backward compatible). Major versions may change required fields or remove operations (breaking). Services can support multiple schema versions simultaneously.

  5. Cross-vendor portability. If Salesforce and HubSpot both publish crm.opportunity schemas that share a common base schema, switching between them is a configuration change — point your AI agent at a different endpoint.


Authorization Model

Key-to-Permission Mapping

When a customer subscribes to a service, the service maps the customer's public keys to permission sets:

{
  "kind": "xp.authorization.grant",
  "payload": {
    "grantee": "customer-employee-public-key",
    "permissions": ["read", "write"],
    "entities": ["salesforce.opportunity", "salesforce.account", "salesforce.contact"],
    "constraints": {
      "salesforce.opportunity.query": { "filter": { "field": "owner", "op": "eq", "value": "$self" } }
    },
    "valid_from": "2026-01-01T00:00:00Z",
    "valid_until": "2027-01-01T00:00:00Z"
  }
}

This grant says: "This public key can read and write opportunities, accounts, and contacts, but can only query opportunities they own. The grant expires on January 1, 2027."

Seat Management

Adding a seat: the customer's organization root key publishes a new employee key, then the service maps permissions to that key. One event each. Total time: seconds.

Removing a seat: the organization publishes a key revocation event. The service receives it and immediately stops accepting events from that key. One event. Immediate.

Transferring a seat: revoke the old key, authorize the new key. Two events.

No user management portal. No SCIM provisioning. No SAML configuration. No SSO setup. Keys and events.

Permission Enforcement

Every incoming event is checked against the sender's permission set:

  1. Verify signature. Is this event actually from this sender? (Ed25519 signature verification)
  2. Check key status. Has this key been revoked? (Check revocation feed)
  3. Verify chain of authority. Is this key authorized by a recognized organization? (Walk the key hierarchy)
  4. Check permissions. Does this key have permission for this event kind? (Permission set lookup)
  5. Apply constraints. Does this event satisfy any constraints on the permission? (Constraint evaluation)
  6. Process. If all checks pass, process the event.

Steps 1-3 are purely cryptographic — no service-side state required. Steps 4-5 require service-side state (permission sets, revocation status, entity-level ACLs, tenant mappings, billing status). This state can be heavily cached — permission sets loaded into memory with TTL-based invalidation, revocation status tracked via bloom filters or Merkle logs — but it cannot be eliminated entirely. The goal is to minimize I/O per event, not to pretend service-side state doesn't exist.


Key Management & Recovery

Cryptographic identity is powerful but introduces real-world risks that password-based systems handle (poorly, but familiarly): lost devices, forgotten credentials, inheritance, corporate offboarding, and key compromise. XProtocol must handle these without reintroducing a trusted central party.

The Problem

For power users, private key custody is natural — they already use hardware wallets, YubiKeys, and GPG keys. For everyone else, "if you lose your key, you lose your identity" is terrifying and unacceptable. Any protocol that requires ordinary people to manage cryptographic keys directly will fail at mass adoption.

Key Recovery Model

XProtocol uses a social recovery model — the same approach used by Ethereum smart contract wallets and some modern cryptocurrency wallets:

  1. Recovery guardians. The user designates 3-5 trusted parties (spouse, close friends, family members, a lawyer) as recovery guardians. Each guardian receives a key shard — a fragment of the recovery key that is useless alone.
  2. Threshold recovery. To recover a lost key, the user must obtain shards from a threshold of guardians (e.g., 3 of 5). The shards are combined to reconstruct the recovery key, which can authorize a new keypair as the user's identity.
  3. No single point of failure. No single guardian can recover (or steal) the identity. No corporation holds a master key. The trust is distributed across people the user actually trusts.

Recovery Flow

User loses device
     │
     ▼
User obtains new device, initiates recovery
     │
     ▼
User contacts guardians (in person, phone, video call)
     │
     ▼
Each guardian authenticates the user (they know the person)
and releases their shard via XProtocol event to the new device
     │
     ▼
Threshold met (3 of 5 shards collected)
     │
     ▼
Recovery key reconstructed → new keypair generated
     │
     ▼
Old key revoked, new key published as successor
     │
     ▼
All services and contacts update to new key automatically

Recovery for Non-Technical Users

Social recovery works for crypto-native users who understand keypairs and shards. For everyone else — and "everyone else" is 99% of the population — XProtocol provides graduated recovery options with increasing convenience and decreasing sovereignty:

Tier 1 — Cloud-assisted encrypted backup (recommended default). During setup, the user's recovery key is encrypted with a passphrase and backed up to an XProtocol relay (or multiple relays). To recover, the user enters their passphrase on a new device. The relay stores only ciphertext — it cannot access the key. This is familiar (it feels like a password) and self-sovereign (no third party can access the key without the passphrase). The AI guides the user through setup: "Choose a recovery passphrase. This is the only way to recover your identity if you lose all your devices. Write it down and keep it safe."

Tier 2 — Social recovery (power users). Guardian-based shard recovery as described above. More secure (no single passphrase to guess) but requires coordinating with other people.

Tier 3 — Family plans. Family members' devices automatically serve as recovery guardians for each other. Mom's phone holds a shard for Dad's key and vice versa. If Dad loses his phone, Mom's phone participates in recovery without Mom needing to understand what a shard is — the AI handles it: "Dad is recovering his Explan identity. Tap to confirm it's really him."

Tier 4 — Enterprise recovery. The organization's admin key can issue a new employee key at any time. The employee doesn't manage their own recovery — IT does. This is the corporate model people already understand.

The "grandma lost her phone" scenario. Grandma set up Explan with a cloud backup (Tier 1) and her daughter as a family guardian (Tier 3). She gets a new phone. The AI walks her through: "Welcome back. Enter your recovery passphrase, or tap here to recover through a family member." She doesn't remember the passphrase. She taps "family member." Her daughter gets a notification: "Mom is recovering her Explan identity. Is this really her?" Daughter confirms. Grandma's identity is restored. Total time: 2 minutes. Zero understanding of cryptography required.

Device-Level Key Protection

The private key never exists in plaintext outside the device's secure enclave (Titan chip on Pixel, Secure Enclave on Apple, ARM TrustZone on others). The key is:

  • Encrypted at rest in the secure enclave, unlockable via biometric (fingerprint, face) or PIN.
  • Never exportable. Signing operations happen inside the secure enclave. The key material never enters user-space memory.
  • Backed up as shards. The recovery shard distribution happens once during setup. The shards are encrypted to each guardian's key.

Multi-Device Key Synchronization

When the user has multiple devices (phone, laptop, tablet), the keypair needs to be available on all of them. Options:

  • Same key on all devices. The key is transferred to new devices via a secure pairing process (QR code scan, NFC tap, or shard-based recovery). Each device stores the key in its own secure enclave.
  • Device-specific sub-keys. Each device gets its own keypair, signed by the master key. Services accept events from any sub-key in the chain. If one device is lost, only that sub-key is revoked — the master identity and other devices are unaffected.

The sub-key model is more secure (a compromised device doesn't compromise the master identity) and is the recommended approach.

Corporate Key Management

Organizations have additional requirements: employee onboarding, offboarding, role changes, and compliance.

  • Onboarding: The organization's admin key signs a new employee keypair. The employee's key inherits organizational permissions. One event.
  • Offboarding: The admin key publishes a revocation event for the employee's key. All services immediately stop accepting events from that key. One event. Instant.
  • Role changes: Revoke old permission grants, issue new ones. Two events.
  • Compliance: The organization maintains a signed log of all key authorizations and revocations. Auditors can verify the complete history of who had access to what, when, signed by whom.
  • Corporate key escrow: Organizations can optionally escrow employee keys (or require device-specific sub-keys that the organization can revoke unilaterally). This is the organization's policy choice, not a protocol requirement.

Inheritance

Digital inheritance is handled through the same social recovery mechanism. The user designates inheritance guardians (family members, attorney, executor) with recovery shards. Upon death, the guardians coordinate to recover the identity. The recovered key can then transfer ownership of data, subscriptions, and service relationships to the heir's key.

Alternatively, the user can pre-authorize a succession key: "If my key is inactive for 180 days, this succession key becomes authoritative." This is a dead-man's switch implemented as an XProtocol event with a time-delayed activation.


Transactional Guarantees

Single-Event Transactions

Most operations are inherently transactional — a create either succeeds or fails, an update either applies or doesn't. The response event indicates success or failure:

{
  "kind": "salesforce.opportunity.create.result",
  "correlation_id": "abc-123",
  "payload": {
    "status": "success",
    "entity": { "id": "opp-789", "name": "Acme Deal", ... }
  }
}

or:

{
  "kind": "salesforce.opportunity.create.error",
  "correlation_id": "abc-123",
  "payload": {
    "status": "error",
    "code": "VALIDATION_FAILED",
    "errors": [
      { "field": "amount", "message": "Amount must be greater than zero" }
    ]
  }
}

Multi-Event Transactions

For operations that span multiple entities or services, XProtocol supports saga patterns:

{
  "kind": "xp.transaction.begin",
  "correlation_id": "tx-001",
  "payload": {
    "steps": [
      { "kind": "bank.account.debit", "payload": { "account": "A", "amount": 10000 } },
      { "kind": "bank.account.credit", "payload": { "account": "B", "amount": 10000 } }
    ],
    "rollback_on_failure": true
  }
}

The service endpoint processes each step sequentially. If any step fails, previous steps are rolled back. The response includes the outcome of every step:

{
  "kind": "xp.transaction.result",
  "correlation_id": "tx-001",
  "payload": {
    "status": "success",
    "steps": [
      { "step": 0, "status": "committed", "result": { ... } },
      { "step": 1, "status": "committed", "result": { ... } }
    ]
  }
}

Cross-Service Coordination (Optional)

When a workflow spans multiple service endpoints (debit from Bank A, credit to Bank B), XProtocol provides optional coordination primitives. These are not default protocol guarantees — true distributed transactions across independent vendors are theoretically clean and practically brutal. XProtocol takes a pragmatic approach:

Preferred: Saga pattern with compensating actions. Each step is an independent event. If step 3 fails, the coordinator publishes compensating events to reverse steps 1 and 2. This is eventually consistent, not ACID, but it works reliably across independent services that don't share state.

Step 1: Debit Bank A → success
Step 2: Credit Bank B → failure
Step 3: Compensate → Credit Bank A (reverse step 1)
Step 4: Notify user → "Transfer failed, Bank B rejected. Your funds have been returned."

Available but use with caution: Two-phase commit. For services that explicitly support it, XProtocol offers 2PC coordination:

  1. Prepare phase: The coordinator sends prepare events. Each service locks resources and responds with prepared or failed.
  2. Commit phase: If all respond prepared, the coordinator sends commit. Otherwise, rollback.

Mandatory safeguard — epoch limits. Every xp.transaction.begin event includes a max_epoch field (default: 30 seconds). If a commit or rollback signal isn't received within the epoch, participating services automatically release locks and discard pending state modifications — without waiting for the coordinator. This prevents the classic 2PC failure mode where a crashed coordinator leaves resources locked indefinitely.

{
  "kind": "xp.transaction.begin",
  "payload": {
    "max_epoch_seconds": 30,
    "steps": [...],
    "on_epoch_expiry": "rollback"
  }
}

The coordinating agent can be the user's AI agent or a dedicated transaction coordinator service. For most real-world workflows (dinner planning, appointment booking, purchase flows), the saga pattern is sufficient and more resilient. 2PC is available for scenarios that genuinely require atomicity across services.


Encryption and Privacy

End-to-End Encryption

Event payloads are encrypted using XChaCha20-Poly1305 with ephemeral X25519 ECDH key agreement and HKDF-SHA256 key derivation. This means:

  • Only the intended recipient can read the payload.
  • Even if transport is compromised, payload data is protected.
  • The service endpoint's private key is required to decrypt incoming events.

Encryption key model: XProtocol uses two distinct keypairs per identity. The Ed25519 keypair is used exclusively for signing and verifying event signatures. A separate X25519 keypair is used exclusively for ECDH key agreement during encryption and decryption. Both keypairs are generated together at identity creation and stored in secure storage. The recipient's X25519 public key is exchanged during the pairing handshake alongside the Ed25519 public key.

Encryption algorithm: 1. Sender generates an ephemeral X25519 keypair (fresh per message) 2. Sender performs X25519 ECDH between the ephemeral private key and the recipient's X25519 public key → shared secret 3. Sender derives a 32-byte symmetric key via HKDF-SHA256 (info: 'xprotocol-v1-message', no salt) 4. Sender generates a 24-byte random nonce and encrypts with XChaCha20-Poly1305 5. The encrypted payload envelope contains: ciphertext + Poly1305 authentication tag, ephemeral public key (32 bytes), nonce (24 bytes) 6. Recipient performs ECDH with their X25519 private key + the ephemeral public key, re-derives the same symmetric key, and decrypts

XProtocol does not depend solely on TLS for payload confidentiality, but TLS (or equivalent transport security) remains recommended for all connections. TLS provides transport integrity, endpoint authentication, metadata privacy, resistance to downgrade attacks, and compliance with enterprise security expectations. XProtocol's end-to-end encryption is a defense-in-depth layer, not a TLS replacement.

Metadata Privacy

Event headers (kind, sender, recipient, timestamp) are visible to transport infrastructure even with TLS, since relays need routing information. For enterprise and privacy-sensitive scenarios, XProtocol uses mandatory envelope encryption: the entire event (including headers) is wrapped in an encrypted outer event addressed to a relay. The relay decrypts the outer routing layer and forwards the inner event. The relay sees the destination but not the operation type, the sender's identity, or any payload data.

For enterprise deployments, envelope encryption is not optional — it is the standard transport mode. The outer packet header exposes only the relay endpoint, keeping all internal operation metadata completely opaque. This prevents traffic analysis attacks where high-frequency metadata patterns could reveal corporate strategies or personal routines.

Data Residency

Because events are encrypted end-to-end, they can be routed through any infrastructure without data residency concerns. A European customer's events can transit through US-based relays without exposing EU personal data to US jurisdiction — the relays see only ciphertext.


AI Agent Integration

How an AI Agent Uses XProtocol

When a user says "Show me all deals over $100K closing this quarter," the AI agent:

  1. Identifies the service. The user's CRM is Salesforce. The agent knows Salesforce's endpoint key from the user's service configuration.

  2. Reads the schema. The agent retrieves (or has cached) the Salesforce opportunity schema. It knows the available fields, types, and operations.

  3. Composes the event. Using GBNF-constrained generation, the LLM produces a valid query event:

{
  "kind": "salesforce.opportunity.query",
  "payload": {
    "filter": {
      "and": [
        { "field": "amount", "op": "gte", "value": 100000 },
        { "field": "close_date", "op": "between", "value": ["2026-04-01", "2026-06-30"] }
      ]
    },
    "sort": [{ "field": "amount", "direction": "desc" }],
    "fields": ["name", "amount", "stage", "close_date", "account.name"]
  }
}
  1. Signs and encrypts. The agent signs the event with the user's key and encrypts the payload to Salesforce's endpoint key.

  2. Sends. The event is transmitted via WebSocket to Salesforce's XProtocol endpoint.

  3. Receives response. Salesforce verifies the signature, checks permissions, executes the query, and returns a response event.

  4. Presents results. The agent generates a UI manifest (table, chart, or summary) from the response data and renders it for the user.

The user said one sentence. The AI handled schema lookup, event composition, authentication, encryption, transport, response parsing, and UI generation. No API documentation. No integration code. No login screen.

Schema-to-Grammar Compilation

The most critical AI integration feature: XProtocol schemas can be compiled into GBNF grammars for constrained LLM generation. This means the LLM physically cannot produce an invalid event — the grammar enforces the schema at the token level.

schema: salesforce.opportunity.create
  required: name (string, max 255), stage (enum), account (reference)
  optional: amount (decimal), close_date (date), description (text)

compiled grammar:
  root ::= "{" name-field "," stage-field "," account-field optional-fields "}"
  name-field ::= "\"name\":\"" [^"]{1,255} "\""
  stage-field ::= "\"stage\":\"" ("Prospecting"|"Qualification"|"Proposal"|"Negotiation"|"Closed Won"|"Closed Lost") "\""
  account-field ::= "\"account\":\"" uuid "\""
  ...

This eliminates the "hallucinated JSON" problem entirely. The LLM generates valid events by construction, not by hope.


Namespace Governance & Extensibility

Namespace Ownership

Event kind namespaces are owned by the entity that controls the corresponding domain:

  • salesforce.* → owned by Salesforce (verified via DNS TXT record linking domain to XProtocol public key)
  • stripe.* → owned by Stripe
  • acme-corp.* → owned by Acme Corp
  • xp.* → reserved for core protocol operations (managed by the XProtocol specification)

This prevents namespace collisions without requiring a central registry. If you control example.com, you can publish events under example.*. Verification is a DNS lookup — the same mechanism that secures email (DKIM/DMARC) and web certificates.

Vendor Extensions

Vendors extend their namespace freely. Salesforce can add salesforce.ai-scoring.predict without coordinating with anyone. The namespace is theirs.

Community Extensions

For shared concepts that span vendors (e.g., a common CRM schema that both Salesforce and HubSpot could implement), community namespaces use a reverse-domain convention:

  • org.esp-community.crm.opportunity.* — community-defined CRM schema
  • org.esp-community.ecommerce.order.* — community-defined e-commerce schema

Community schemas are proposed and ratified through the open proposal process. Vendors optionally implement them alongside their proprietary schemas, enabling cross-vendor portability.

Core Protocol Namespace

The xp.* namespace is reserved for protocol-level operations that all implementations must support:

xp.schema.request / xp.schema.response     — fetch a specific schema by name (Phase 2)
xp.schema.describe / xp.schema.describe.result  — discover schemas by intent (Phase 1)
xp.schema.refresh                           — cache invalidation signal
xp.endpoint.announce
xp.authorization.grant / xp.authorization.revoke
xp.transaction.begin / xp.transaction.result
xp.ack
xp.error
xp.subscription.confirmed
xp.key.revoke
xp.key.recover

Changes to the xp.* namespace follow the formal proposal process and require broad consensus before adoption.

Namespace Disputes & Security

Malicious lookalikes. An attacker could register sa1esforce.com (with a numeral 1) and publish events under sa1esforce.*. Defenses: endpoint directories flag namespaces that are visually similar to established namespaces. AI agents compare new endpoints against known legitimate endpoints and warn users: "This service claims to be Salesforce but uses a different domain. Proceed with caution." DNS-based verification makes spoofing difficult (the attacker would need to control the lookalike domain's DNS), but social engineering remains a risk.

Versioning disputes. When a community schema (e.g., org.esp-community.crm.opportunity) evolves, contributors may disagree on breaking changes. The governance model follows semantic versioning strictly: minor versions add fields (non-breaking), major versions can change structure (breaking). Multiple major versions coexist. Services declare which versions they support. If the community forks over a dispute, both forks coexist under different version numbers — the protocol doesn't prevent forks, it accommodates them.

Compatibility certification. Vendors can self-certify compatibility with community schemas by publishing a xp.compatibility.attestation event listing which community schemas and versions they implement. Third-party compatibility testing services can independently verify and publish their own attestation. There is no central certification authority — compatibility is verifiable, not gatekept.


Error Taxonomy

Standardized error codes are critical for AI agent robustness. When an event fails, the agent must understand WHY to determine the correct response — retry, modify, escalate, or inform the user.

Error Response Structure

{
  "kind": "xp.error",
  "correlation_id": "abc-123",
  "payload": {
    "code": "AUTHORIZATION_INSUFFICIENT",
    "category": "authorization",
    "severity": "fatal",
    "message": "Key does not have 'write' permission for salesforce.opportunity",
    "details": {
      "required_permission": "write",
      "entity": "salesforce.opportunity",
      "sender_permissions": ["read"]
    },
    "retry_eligible": false,
    "documentation_url": "https://xp.salesforce.com/errors/AUTHORIZATION_INSUFFICIENT"
  }
}

Error Categories and Codes

Category Code Severity Retry Description
validation FIELD_REQUIRED fatal no A required field is missing
FIELD_INVALID_TYPE fatal no Field value doesn't match the schema type
FIELD_OUT_OF_RANGE fatal no Value exceeds min/max constraints
FIELD_INVALID_ENUM fatal no Value not in allowed enum set
SCHEMA_VERSION_UNSUPPORTED fatal no Schema version not supported by endpoint
authorization KEY_UNKNOWN fatal no Sender key not recognized
KEY_REVOKED fatal no Sender key has been revoked
AUTHORIZATION_INSUFFICIENT fatal no Key lacks required permissions
AUTHORIZATION_EXPIRED fatal no Permission grant has expired
CONSTRAINT_VIOLATED fatal no Event violates a permission constraint
identity SIGNATURE_INVALID fatal no Event signature verification failed
CHAIN_OF_AUTHORITY_BROKEN fatal no Key hierarchy verification failed
EVENT_EXPIRED fatal no Event timestamp past expires field
EVENT_DUPLICATE fatal no Event ID already processed (replay)
resource ENTITY_NOT_FOUND fatal no Referenced entity does not exist
ENTITY_ALREADY_EXISTS fatal no Entity with this ID already exists
ENTITY_LOCKED transient yes Entity locked by another transaction
ENTITY_DELETED fatal no Entity has been deleted
rate_limit RATE_LIMIT_EXCEEDED transient yes Too many requests; retry after delay
QUOTA_EXCEEDED fatal no Account quota exhausted for billing period
system ENDPOINT_UNAVAILABLE transient yes Service temporarily unavailable
INTERNAL_ERROR transient yes Unexpected server error
TIMEOUT transient yes Processing exceeded time limit
DEPENDENCY_FAILED transient yes Downstream service failed
transaction TRANSACTION_CONFLICT transient yes Concurrent modification conflict
TRANSACTION_ROLLBACK fatal no Transaction was rolled back
STEP_FAILED fatal no A transaction step failed

AI Agent Error Handling

The category, severity, and retry_eligible fields enable AI agents to handle errors programmatically:

  • Fatal + not retryable: Inform the user. "I don't have permission to create opportunities in your CRM. You'd need to ask your admin to grant write access."
  • Transient + retryable: Retry automatically with exponential backoff. Only inform the user if retries are exhausted.
  • Validation errors: Examine details, fix the event, and resubmit. "The CRM requires a close date — when should I set it to?"

Endpoint Discovery & Relay Infrastructure

Discovery Overview

XProtocol's identity model is key-based, not address-based. Every participant is identified by their Ed25519 public key — permanent regardless of IP address, network, or physical location. Discovery is the process of mapping a public key to a currently reachable transport path.

The full discovery system — including all transport mechanisms, the trust tier model, physical presence transports, and the visual place recognition and physical context binding primitives — is specified in XProtocol-Discovery-Spec.md. This section summarizes the service endpoint discovery hierarchy for AI agents and services.

Discovery Hierarchy

How does an AI agent find the XProtocol endpoint for a service?

Level 1 — DNS. Services publish an XProtocol endpoint record as a DNS TXT record:

_xp.salesforce.com TXT "v=xp1 endpoint=wss://xp.salesforce.com/v1 key=ed25519:abc123..."

This is analogous to how email uses MX records and DKIM uses TXT records. Any AI agent can discover a service's XProtocol endpoint by querying DNS. No central directory required.

Level 1b — Well-known URL fallback. For services that don't control DNS directly (subdomains, hosted platforms), a well-known HTTP endpoint serves the same information:

GET https://salesforce.com/.well-known/xprotocol-endpoint

{
  "version": "xp1",
  "endpoint": "wss://xp.salesforce.com/v1",
  "public_key": "ed25519:abc123...",
  "schema_url": "https://xp.salesforce.com/schema"
}

This follows the same pattern as .well-known/openid-configuration and .well-known/security.txt.

Level 2 — Seed directories. A small set of curated, cryptographically-signed endpoint directories bootstrap initial discovery. These are analogous to DNS root servers — multiple independent operators, no single point of control. Each directory publishes a signed list of verified XProtocol endpoints with metadata (category, rating, schema summary). AI agents ship with a default set of seed directories and can add or remove them.

Level 3 — Relay discovery. For peer-to-peer communication (not services), users publish their preferred relay endpoints as part of their public key metadata. "To reach me, connect to relay.example.com." AI agents discover relays by looking up the recipient's key metadata.

Level 4 — Local cache. Once an agent has discovered an endpoint, it caches the information. Subsequent interactions skip discovery entirely.

Relay Architecture

XProtocol relays serve two functions:

  1. Message routing. Store-and-forward for events when the recipient is offline. The relay holds encrypted events until the recipient connects and retrieves them.
  2. Connection brokering. When both parties are online, the relay facilitates a direct WebSocket connection. Once established, events flow directly — the relay exits the path.

Relays are interchangeable and untrusted. They see only ciphertext. Users can run their own relays (self-sovereignty) or use managed relays (convenience). Multiple relays can be used simultaneously for redundancy.

Relays do NOT: - Decrypt event payloads (they don't have the keys) - Authenticate senders (that's the recipient's job via signature verification) - Enforce authorization (that's the service endpoint's job) - Store events permanently (configurable retention, default 30 days)


XProtocol Event Store

The Concept

A standard XProtocol relay stores events transiently and discards them after delivery or after a retention window expires. An XProtocol Event Store is a relay that retains events permanently and exposes them as a queryable, cryptographically-access-controlled dataset. It is simultaneously a message store, an audit log, a queryable database, and a real-time event stream — with a security model that no traditional database can replicate.

The event store is not a new protocol concept. It is a natural extension of what the relay already does, combined with XProtocol's existing structured query model. The only additions are: persistent retention, a metadata index, and the xp.store.* schema family for querying stored events.

Why This Is Different From a Database

Traditional databases bolt access control on after the fact. An administrator configures roles, grants, and ACLs. The access control system can be misconfigured. A database administrator with sufficient privilege can bypass it. An attacker who compromises the database administrator's credentials inherits all access.

The XProtocol event store inverts this model entirely. The data carries its own access control. Every event is signed by its creator (proving authorship) and encrypted to its recipient (proving access rights). The event store enforces what the cryptography has already established — it does not make access control decisions, it enforces cryptographic ones.

Consequences:

  • A compromised store operator cannot read event payloads. They see only ciphertext. There is no credential to steal that grants payload access.
  • Access cannot be misconfigured. The recipient key IS the access control list. Not a configuration file. Not a role mapping. The ciphertext itself.
  • Provable authorship on every record. Every event is signed by its creator's private key. You cannot insert a document and attribute it to someone else. You cannot modify a stored event without invalidating its signature.
  • Provable query history. Every query is itself a signed event. The store has a cryptographically verifiable record of who queried what and when — not a log an administrator could tamper with, but a signed record the querier themselves produced.

The Access Model

The fundamental access rule is simple and enforced cryptographically:

A key may retrieve any event in which it appears as either sender or recipient.

No exceptions. No administrative overrides. No role-based ACL that could be misconfigured. A key can see events it wrote or events written to it — and nothing else. The store verifies this by checking the unencrypted sender and recipient fields on each event against the requesting key, then returns matching ciphertext. The requesting client decrypts locally.

For organizational key hierarchies, the access rule extends naturally: a parent key may query events belonging to any child key it has authorized, because it signed the child key into existence. An organization's root key can retrieve the full event history of any employee key in its hierarchy. A department key can retrieve events from all employee keys it has signed.

What Is Queryable Without Decryption

Event metadata — the fields that are never encrypted — forms a rich query index:

Metadata Field Queryable Notes
id (content hash) Yes Exact lookup by event fingerprint
sender Yes All events from a given key
recipient Yes All events addressed to a given key
kind (schema type) Yes All events of a specific operation type
timestamp Yes Time-range queries
expires Yes Find events still within validity window
correlation_id Yes Reconstruct full request-response chains
schema_version Yes Filter by protocol version

These fields alone support a surprisingly complete query model: conversation reconstruction, audit trails, operation analytics, compliance reporting — all without decrypting a single event.

Payload-level queries (filtering on fields inside the encrypted payload) require client-side decryption. The store returns matching ciphertext based on metadata filters; the client decrypts and applies secondary filters locally. For high-volume payload-level queries, trusted execution environments (TEEs) can run the decryption and filtering server-side without exposing keys to the store operator — this is an advanced optional extension.

xp.store.* Schema Family

xp.store.query      — query stored events by metadata filters
xp.store.get        — fetch a specific event by content hash (id field)
xp.store.subscribe  — real-time subscription to new events matching a filter
xp.store.retention  — set TTL or retention policy for events you authored
xp.store.stats      — aggregate metadata statistics without decryption

xp.store.query

{
  "kind": "xp.store.query",
  "payload": {
    "filter": {
      "and": [
        { "field": "kind", "op": "eq", "value": "xp.message.direct" },
        { "field": "timestamp", "op": "between", "value": [1717000000, 1717086400] },
        { "field": "sender", "op": "eq", "value": "<peer-public-key>" }
      ]
    },
    "sort": [{ "field": "timestamp", "direction": "asc" }],
    "page_size": 50,
    "cursor": null
  }
}

Response:

{
  "kind": "xp.store.query.result",
  "payload": {
    "total_matching": 142,
    "returned": 50,
    "events": [ "<XpEvent>", "<XpEvent>", "..." ],
    "next_cursor": "cursor-token-abc"
  }
}

The events array contains encrypted XpEvent objects. The client decrypts each payload locally using its private key. The store has returned ciphertext only — it has not read the messages.

xp.store.stats

Aggregate metadata queries that never require decryption:

{
  "kind": "xp.store.stats",
  "payload": {
    "group_by": "kind",
    "filter": { "field": "timestamp", "op": "gte", "value": 1717000000 }
  }
}

Response:

{
  "kind": "xp.store.stats.result",
  "payload": {
    "groups": [
      { "kind": "xp.message.direct", "count": 1247, "first": 1717000123, "last": 1717086000 },
      { "kind": "xp.message.ack", "count": 1189, "first": 1717000145, "last": 1717085900 },
      { "kind": "salesforce.opportunity.create", "count": 34, "first": 1717010000, "last": 1717080000 }
    ]
  }
}

This enables analytics dashboards, compliance reporting, and usage metrics — all from metadata alone, without touching the encrypted content.

xp.store.subscribe

Extends the existing subscription model to stored events. A client can subscribe to all future events matching a filter — equivalent to a real-time database trigger:

{
  "kind": "xp.store.subscribe",
  "payload": {
    "filter": { "field": "kind", "op": "eq", "value": "salesforce.opportunity.create" },
    "include_historical": false
  }
}

With "include_historical": true, the store first delivers all past matching events (paginated), then continues with real-time delivery as new events arrive. This collapses event streaming and historical replay into a single subscription primitive.

xp.store.retention

Event authors can declare retention policy for events they created:

{
  "kind": "xp.store.retention",
  "payload": {
    "event_ids": ["sha256-abc", "sha256-def"],
    "policy": "delete_after_days",
    "value": 90
  }
}

Or revoke access to already-stored events (the sender-controlled message lifecycle extension):

{
  "kind": "xp.store.retention",
  "payload": {
    "event_ids": ["sha256-abc"],
    "policy": "revoke_recipient_access",
    "recipient": "<recipient-public-key>"
  }
}

After revocation, the store stops returning the event to the revoked recipient's queries. The ciphertext remains — it has simply been made unfindable to that key. The event is not deleted (for audit trail integrity) but is cryptographically inaccessible to the revoked party.

The Relay-Store Spectrum

There is no hard boundary between a relay and an event store — it is a spectrum of capability:

Capability Basic Relay Event Store
Store-and-forward Yes Yes
Deliver when recipient connects Yes Yes
Discard after delivery Yes Optional
Permanent retention No Yes
Metadata index No Yes
xp.store.query No Yes
xp.store.stats No Yes
xp.store.subscribe with history No Yes
Payload-level queries No Optional (TEE)

An operator can implement any point on this spectrum. A minimal relay implements store-and-forward only. A full event store adds persistent retention, indexing, and the xp.store.* schema. Intermediate implementations are valid — for example, a relay that retains events for 1 year and supports xp.store.query but not xp.store.stats.

What the Event Store Replaces

For event-driven architectures and AI agent infrastructure, the XProtocol event store subsumes an entire traditional data stack:

Traditional Component Replaced By
NoSQL document store (MongoDB, DynamoDB) Event store — permanent encrypted event retention with metadata queries
Event streaming (Kafka, Kinesis) Relay + xp.store.subscribe — real-time delivery with historical replay
Audit logging system (Splunk, ELK) The event store IS the audit log — every event is already signed and timestamped
Column/row-level security (Lake Formation) Not needed — recipient key IS the row-level security
Data encryption at rest Not needed — data arrives already encrypted; the store never holds plaintext
SIEM for security event correlation xp.store.query across the event store with filter on security-relevant schemas
Search index (Elasticsearch) Metadata index on unencrypted fields supports the majority of search use cases

A single XProtocol event store deployment provides all of these with stronger security guarantees than any of the individual components it replaces — because the access model is cryptographic, not administrative.

Applications

Portable communication history. A messaging application that stores its events in an XProtocol event store gives users portable, device-independent history. A new device recovers the full conversation history by querying the store with the user's private key. The store operator has never read a single message.

Organizational audit trail. Every operation performed by every employee key is a signed event in the store. Auditors query the store with time-range and operation-type filters to produce compliance reports. The audit trail cannot be tampered with — each event's signature proves it came from the claimed sender at the claimed time.

AI agent memory. An AI agent stores its interactions, decisions, and tool invocations as XProtocol events. The store becomes the agent's long-term memory — queryable, verifiable, and portable across agent implementations. "What did I do last Tuesday about the customer order?" is a metadata query against the agent's event store.

Cross-service data fabric. Multiple services write events to a shared event store. Authorized consumers query across services without any service needing to expose a data export API. The event store is the integration layer — signed events from every service, queryable by any authorized key.

Regulatory evidence vault. Financial services, healthcare, and legal organizations store compliance-critical events in the event store. Every record has cryptographic proof of who created it, when, and that it has not been modified since. xp.store.retention prevents premature deletion. The event store satisfies evidence integrity requirements that traditional audit logs cannot.

Implementation Note: The Store Is an Optional Extension

The xp.store.* schema family is an optional XProtocol extension. A basic relay that does not implement event store capabilities is a fully valid XProtocol implementation. The event store is adopted when persistent, queryable event history is needed — which is often, but not universally.

Implementations that support xp.store.query declare this capability in their xp.endpoint.announce event under capabilities: ["xp.store.*"]. Clients discover store capability through the normal schema discovery mechanism.


XProtocol Graph Store

The XProtocol Graph Store extends the Event Store with a structured annotation system: a mutable, authorized, auditable dictionary of typed metadata attached to each stored event — outside the signed payload, queryable without decryption, updated only by authorized keys, with every mutation itself a signed permanent event.

Full specification: XProtocol-Graph-Store-Spec.md

The Core Model

Every event stored in a Graph Store has two layers:

Layer 1 — The signed, immutable XpEvent. The cryptographic record. Permanent, unforgeable, tamper-evident. Defined by the core XProtocol specification.

Layer 2 — The annotation envelope. A structured dictionary attached to the stored event by the Graph Store. Mutable, unencrypted, authorized. Every write to the annotation envelope is effected by a signed xp.graph.annotate event — there are no silent mutations. The annotation history is itself a first-class queryable dataset in the store.

Annotation Namespaces

The annotation envelope is organized into eight standard namespaces:

thread.* — Conversation threading. Links events into reply chains and threaded conversations without a separate thread table or entity. A thread is a query — filter: { annotations.thread.thread_id == 'X' } — not a database object. Events can belong to multiple threads simultaneously.

recipient.* — Personal inbox state. Per-recipient read/unread status, folders, stars, snooze, priority, and private notes. Authorization is RECIPIENT_ONLY — the sender never sees a recipient's inbox state. Different recipients of the same event have completely independent views. This is the full email inbox model without a shared inbox server.

trace.* — Distributed observability. Ten distinct identifiers covering every level of causality and context — trace_id for the end-to-end operation, span_id for this system's contribution, causation_id for the specific event that caused this one, saga_id for the transaction, session_id for the user session, and five more. All SENDER_ONLY and immutable. The complete trace of an operation across any number of services is a single query: filter: { annotations.trace.trace_id == 'trace-X' }. No separate tracing infrastructure required.

groups — Universal membership. Any event, user key, or data record can be a member of any number of named groups simultaneously. Groups are queries, not database tables. A project group, a client group, and a time-period group are all queryable with the same filter primitive. Group definitions are themselves events stored in the Graph Store.

links — Typed relationships. Directed, typed edges between events: caused_by, supersedes, reply_to, references, part_of, blocks, blocked_by, related_to, and custom application-defined types. The xp.graph.traverse operation follows link edges through the graph to any specified depth. The external_refs sub-field provides typed foreign keys to entities in external non-XProtocol systems — Salesforce opportunities, Jira tickets, Stripe invoices, GitHub pull requests — creating a universal cross-system reference model.

workflow.* — Process state. Current workflow step, assignment, completion history, due dates, and terminal status. Any event can be a workflow artifact. The workflow state is the annotation; no separate workflow engine or database entity is required. Workflow transitions are annotation events — the full process history is queryable and tamper-evident.

versioning.* — Version chains. Logical versioning on immutable events. A new version supersedes prior versions by annotation, not mutation. The is_current field (STORE_MANAGED) is updated automatically when a newer version arrives. The full version history of any entity is always queryable.

ai.* — AI semantic tags. Intent, sentiment, named entities, topics, language, summary, and embedding references — derived by AI agents from decrypted payload content and stored as queryable plaintext annotations. The store never receives the decrypted content; only the derived semantic tags are stored. This creates a persistent semantic index that makes encrypted content discoverable by meaning without re-processing.

Annotation Authorization

Every annotation field declares its authorization level, enforced on every write:

Level Who Can Write
SENDER_ONLY Only the original event sender's key
RECIPIENT_ONLY Only the original event recipient's key
PARTICIPANTS Either sender or any recipient
AUTHORIZED_KEYS Explicitly granted third-party keys
STORE_MANAGED Only the store itself
ANY_VERIFIED Any key with a valid signature

The xp.graph.* Schema Family

xp.graph.annotate                    — add or update annotations on a stored event
xp.graph.annotate.bulk               — annotate multiple events in one operation
xp.graph.annotation.history         — full mutation history for an annotation field
xp.graph.annotation-schema.define   — declare annotation schema for an event kind
xp.graph.traverse                   — follow link edges through the event graph
xp.graph.group.define               — create a named group
xp.graph.group.list                 — list groups accessible to the requesting key
xp.graph.group.membership.add       — add an entity to a group
xp.graph.group.membership.remove    — remove an entity from a group

What the Graph Store Replaces

A Graph Store deployment answers queries that currently require assembling multiple distinct infrastructure components:

Traditional Component Graph Store Equivalent
Graph database (Neo4j) Typed link annotations + xp.graph.traverse
Distributed tracing (Jaeger, Zipkin, OTel) trace.* namespace — signed by each system, tamper-evident
Email inbox server (IMAP) recipient.* namespace — per-recipient, private, no shared server
Workflow engine (Temporal, Airflow) workflow.* namespace — state on events, no separate DB
Version control for records versioning.* namespace — immutable history, cryptographic chain
AI semantic search ai.* namespace — persistent index without re-processing
Cross-system foreign keys external_refs — universal reference across all integrated services
Observability platform trace.* + xp.store.stats — no collector infrastructure
Audit log of state changes Annotation history — every mutation is a signed event

Implementation Note: Graph Store Is an Optional Extension

A Graph Store is an Event Store that additionally implements xp.graph.*. An Event Store that does not implement graph annotations is a fully valid implementation. Implementations declare graph capabilities in their xp.endpoint.announce event:

"capabilities": [
  "xp.store.*",
  "xp.graph.annotate",
  "xp.graph.annotation.history",
  "xp.graph.traverse",
  "xp.graph.group.*"
]

Regulatory Compliance

GDPR

XProtocol's architecture is inherently GDPR-friendly:

  • Data minimization. Events contain only the data needed for the specific operation. No session cookies, no tracking pixels, no behavioral telemetry.
  • Right to erasure. The user publishes a xp.data.erasure-request event to a service. The service must delete all data associated with that key and confirm via response event. The request and confirmation are cryptographically signed — auditable proof of compliance.
  • Data portability. The user publishes a xp.data.export-request event. The service returns all data associated with that key in a structured, machine-readable format (XProtocol events). The user's AI agent can import this data into another service instantly.
  • Consent management. Every authorization grant is an explicit, signed event. There is no ambiguity about what the user consented to — the grant specifies exact entities, operations, and constraints. Consent withdrawal is a revocation event.
  • Data residency. Events are end-to-end encrypted. They can transit through any jurisdiction without exposing personal data. The relay in Frankfurt sees the same ciphertext as the relay in Virginia.

SOC 2

  • Audit trail. Every interaction is a signed, timestamped event. The event stream IS the audit log. No separate audit logging infrastructure required.
  • Access control. Key-to-permission mapping with chain-of-authority verification. Every access decision is deterministic and auditable.
  • Change management. Schema versions are tracked. Authorization grants and revocations are logged as events. The complete history of who had access to what, when, is cryptographically verifiable.

HIPAA

  • Encryption. All event payloads are encrypted end-to-end (XChaCha20-Poly1305). Data at rest in the relay is ciphertext. This satisfies HIPAA's encryption requirements for protected health information (PHI).
  • Access controls. Per-entity, per-operation authorization with constraints. "Dr. Smith can read patient records for patients assigned to her" is expressible as a permission constraint.
  • Audit trail. Same as SOC 2 — every access to PHI is a signed event in an immutable log.
  • Business associate agreements. Relay operators are not business associates under HIPAA because they never access PHI — they store and forward ciphertext. This dramatically simplifies the compliance chain.

Auditor Education

Regulators and auditors are unfamiliar with cryptographic protocols. XProtocol implementations should provide: - Compliance mapping documents that explicitly map XProtocol mechanisms to regulatory requirements (control-by-control). - Verification tools that auditors can use to independently verify event signatures, authorization chains, and encryption without understanding the cryptography. - Plain-language audit reports generated from the event stream: "User X accessed record Y at time Z, authorized by grant G, signed by admin key A."


License-Gated Local Data

The Problem

SaaS vendors face a fundamental tension: customers want local data access (faster, offline-capable, better UX), but vendors can't allow it because once data is downloaded, it's uncontrollable. The customer could cancel their subscription and keep the data. They could copy it to unauthorized parties. They could use it in ways that violate the license agreement. The result: vendors force everything through online APIs, sacrificing performance and offline access to maintain control.

XProtocol's cryptographic model resolves this. Data can live locally on the customer's device while remaining cryptographically bound to an active subscription.

How It Works

Dual-key encryption. Data from a vendor is encrypted with a key derived from BOTH the customer's key AND a vendor-issued license token. Neither key alone can decrypt the data. The customer has their private key (permanent). The vendor issues license tokens (ephemeral, time-limited).

{
  "kind": "xp.license.grant",
  "sender": "lexisnexis-endpoint-key",
  "recipient": "customer-key",
  "payload": {
    "license_id": "lic-789",
    "scope": ["lexisnexis.cases.*", "lexisnexis.statutes.*"],
    "data_access": "local_cache_permitted",
    "token": "encrypted-license-token",
    "issued_at": "2026-06-01T00:00:00Z",
    "expires_at": "2026-06-08T00:00:00Z",
    "refresh_url": "wss://esp.lexisnexis.com/v1"
  }
}

License refresh cycle:

Customer device                    LexisNexis
     │                                  │
     │  xp.license.refresh.request     │
     │  (signed with customer key)      │
     │ ──────────────────────────────>  │
     │                                  │  Verify subscription active
     │                                  │  Check payment status
     │  xp.license.grant               │
     │  (new token, 7-day expiry)       │
     │ <──────────────────────────────  │
     │                                  │
     │  Derive new decryption key       │
     │  Local data accessible           │
     │                                  │

When the subscription lapses:

Customer device                    LexisNexis
     │                                  │
     │  xp.license.refresh.request     │
     │ ──────────────────────────────>  │
     │                                  │  Subscription expired
     │  xp.license.denied              │
     │  reason: "subscription_inactive" │
     │ <──────────────────────────────  │
     │                                  │
     │  License token expires           │
     │  Decryption key no longer        │
     │  derivable                       │
     │  Local data → inaccessible       │
     │  ciphertext                      │
     │                                  │

The data is still on the device — it hasn't been deleted. But without a valid license token from the vendor, the decryption key cannot be derived. The data is cryptographically inaccessible.

Why This Is Stronger Than Traditional DRM

Traditional DRM relies on obfuscation — hiding the decryption key somewhere the user can't find it. This is an arms race that DRM consistently loses (every DRM scheme has been cracked). XProtocol's approach is different:

  • The decryption key doesn't exist on the device. It's derived at runtime from the customer's private key + the vendor's license token. Without the token, there is no key to find.
  • The vendor's license token can't be forged. It's signed by the vendor's key. The customer can't create one.
  • The data can't be shared. Even if the customer sends the encrypted data to someone else, the recipient can't decrypt it — they don't have the customer's private key, and even if they did, they don't have a license token issued to their key.
  • The data can't be decrypted after cancellation. The last license token expires. No new token is issued. The decryption key ceases to exist.

Use Cases

Scenario How it works
Legal research (LexisNexis) Case law and statutes cached locally for fast search and offline access. License expires → cached data inaccessible. Renew subscription → data accessible again immediately (no re-download needed).
Financial data (Bloomberg) Market data, research reports, and analytics cached on trader's device. Seat revoked → data inaccessible.
Enterprise software Premium features gated by license token. Feature works while license is active. Expires → feature disabled, UI adapts.
Content licensing (ebooks, courses) Content downloaded for offline reading/viewing. Subscription active → content accessible. Cancelled → content locked. Re-subscribe → content unlocked (still on device).
API response caching Expensive API query results cached locally with license-gated decryption. Customer can use cached results offline for the license duration without re-querying the API.
Professional tools Medical reference databases, engineering specifications, compliance databases. Cached locally for field use. Licensed per-seat, per-year.

Grace Periods and Offline Tolerance

License tokens have configurable expiry windows. A 7-day token means the customer can be offline for up to 7 days without losing access. Vendors choose the window based on their business model:

  • Tight control (1-24 hours): Real-time trading data, premium content
  • Standard (7 days): Most SaaS data, professional tools
  • Lenient (30 days): Educational content, reference materials
  • Perpetual with updates (never expires but stops updating): The customer keeps the data they had at cancellation but receives no new data. The license token gates new data sync, not access to existing data.

Data Recovery on Re-subscription

When a customer re-subscribes, the vendor issues a new license token. The locally cached data — which was never deleted, just cryptographically locked — becomes accessible again instantly. No re-download. No data migration. The ciphertext was always there; now the key exists again.

This is a better customer experience than the current model (cancel → lose everything → re-subscribe → re-download everything) and a better vendor experience (customer retention is higher when re-activation is frictionless).


What XProtocol Replaces

Current technology What it does How XProtocol replaces it
REST APIs Service-to-service communication Event kinds with structured payloads. One protocol instead of thousands of bespoke APIs.
OAuth 2.0 Authentication and authorization Ed25519 signatures on every event. Key-to-permission mapping. No tokens, no flows, no refresh.
API keys Service authentication Public keys. Inherently unforgeable. No rotation ceremony — revoke and reissue instantly.
SAML / SSO Enterprise identity federation Organizational key hierarchies with chain-of-authority verification.
SCIM User provisioning Key authorization events. Add a seat = authorize a key. Remove a seat = revoke a key.
Webhooks Event notifications Subscriptions with persistent delivery. No public endpoint required. Cryptographically verified.
GraphQL Flexible queries Structured query events with filter, sort, field selection, aggregation, and relationship traversal.
OpenAPI / Swagger API documentation Schema contracts. Machine-readable, AI-parseable, grammar-compilable.
MCP AI-to-tool discovery and invocation XProtocol extends MCP's validated insight into the identity and transport layers. Schema contracts compile to generation grammars. The XProtocol MCP Adapter bridges both ecosystems bidirectionally — MCP servers become XProtocol endpoints, XProtocol endpoints become MCP tools. Zero changes to existing systems.
Integration middleware Connecting incompatible systems Universal protocol eliminates incompatibility. No Zapier, no MuleSoft, no custom integration code.
TLS certificates Transport encryption XProtocol does not depend solely on TLS for payload confidentiality — payloads are encrypted end-to-end regardless of transport. TLS remains recommended for transport integrity and metadata privacy.
Audit logging Compliance trail Every event is signed and timestamped. The event stream IS the audit log.
Messaging protocols Person-to-person communication Direct and group messaging via encrypted events. No messaging server, no account, no phone number.
Nostr Decentralized social and messaging XProtocol provides everything Nostr does plus schemas, queries, transactions, and fine-grained authorization. Same Ed25519 identity, compatible keys.
Social media APIs Social feed, reactions, sharing Public and private social events. AI-curated feed — no corporate algorithm.
XMPP / Matrix Federated messaging XProtocol events via relays. Simpler protocol, built-in encryption, AI-native.
WebRTC signaling Real-time communication setup Signaling events for voice/video call negotiation via XProtocol.
DRM / content protection Controlling access to downloaded content License-gated local data. Dual-key encryption binds data to active subscription. No obfuscation arms race.
Software licensing (seats) Managing who can use paid software Key-to-permission grants with expiry. Add seat = authorize key. Remove seat = revoke key. License tokens gate feature access.
SaaS data access control Preventing data retention after cancellation License token expiry makes locally cached data cryptographically inaccessible. Re-subscribe = instant re-access without re-download.

Adoption Path

Phase 1 — Explan-to-Explan

XProtocol is the native protocol for communication between Explan devices. Agent-to-agent coordination, data sharing, capability negotiation — all XProtocol events. This provides the initial implementation, testing ground, and reference implementation.

Phase 2 — Vertical Prestige Integrations

Cold-start physics are brutal. XProtocol needs a few high-value integrations early to prove commercial viability. The target verticals are ones where license-gated local data + compliance features have outsized value:

  • Legal tech (LexisNexis, Westlaw). Attorneys need offline access to case law in courtrooms with no WiFi. License-gated local data solves the vendor's control problem while giving lawyers what they've always wanted. Attorney-client privilege enforcement via sender-controlled message lifecycle is a compliance feature no existing system offers.
  • Financial data (Bloomberg, Refinitiv). Traders need low-latency local data. Compliance teams need audit trails. License gating enables offline terminals without data leakage risk.
  • Healthcare (Epic, Cerner). HIPAA compliance is built into the protocol. License-gated patient data enables field access for home health workers. Sender-controlled records let patients manage their own health data sharing.
  • Engineering/CAD (Autodesk, Siemens). Large design files cached locally for performance. License-gated access solves the "contractor finished the project but kept our IP" problem.

One or two prestige integrations in these verticals would demonstrate commercial value and attract further adoption.

Phase 3 — Capability Adapters as XProtocol Bridges

Community-built capability adapters translate between XProtocol and existing REST/GraphQL APIs. The adapter receives an XProtocol event, translates it to the vendor's REST API call, receives the response, and publishes an XProtocol response event. The user's AI agent speaks XProtocol; the adapter handles the translation.

This provides immediate compatibility with every existing service without requiring vendor adoption.

Phase 4 — Vendor-Native XProtocol Endpoints

As the Explan ecosystem grows, vendors have economic incentive to publish native XProtocol endpoints. A vendor that publishes an XProtocol schema is instantly accessible to every AI agent — no app, no SDK, no integration project. Early adopters gain distribution advantages.

Phase 5 — XProtocol as Industry Standard

When enough vendors support XProtocol natively, the protocol becomes the default integration mechanism — the way HTTP became the default transport, the way JSON became the default format. The integration middleware industry (currently $30B+) is compressed to near zero. The cost of connecting any two systems approaches the cost of exchanging public keys.


Peer-to-Peer Communication

XProtocol is not just a service integration protocol. It is the universal communication protocol for all interactions — person-to-person, person-to-service, agent-to-agent, and service-to-service. The same event model, the same identity, the same encryption, the same transport.

Direct Messaging

{
  "kind": "xp.message.direct",
  "sender": "alice-public-key",
  "recipient": "jake-public-key",
  "correlation_id": "msg-001",
  "payload": {
    "text": "Are we still on for Saturday?",
    "media": []
  }
}

Jake's device receives the event, decrypts the payload, and presents the message. Jake's AI agent evaluates priority and context — if Jake is busy, it might queue the notification. If Jake is idle, it renders the conversation thread.

Response:

{
  "kind": "xp.message.direct",
  "sender": "jake-public-key",
  "recipient": "alice-public-key",
  "correlation_id": "msg-002",
  "payload": {
    "text": "Absolutely! I was thinking 7pm?",
    "reply_to": "msg-001"
  }
}

No messaging server. No account. No phone number required. Two public keys exchanging encrypted events through relays. The relay transports ciphertext — it cannot read the messages.

Group Messaging

{
  "kind": "xp.message.group",
  "sender": "alice-public-key",
  "payload": {
    "group_id": "saturday-dinner-planning",
    "members": ["alice-key", "jake-key", "sarah-key"],
    "text": "Jake suggested 7pm — Sarah, does that work?",
    "reply_to": "msg-002"
  }
}

Group messages are encrypted to each member's key individually (or via a shared group key derived through a key agreement protocol). Members can be added or removed by publishing group membership events signed by the group creator.

Media Sharing

{
  "kind": "xp.message.direct",
  "sender": "alice-public-key",
  "recipient": "jake-public-key",
  "payload": {
    "text": "Check out this restaurant",
    "media": [
      {
        "type": "image/jpeg",
        "size": 2458000,
        "hash": "sha256-of-encrypted-media",
        "url": "xp-relay://media/sha256-hash",
        "thumbnail": "base64-encoded-thumbnail",
        "dimensions": { "width": 4032, "height": 3024 }
      }
    ]
  }
}

Large media files are uploaded to a relay as encrypted blobs, referenced by content hash. The recipient's device downloads and decrypts them. The relay stores ciphertext — it cannot view the media.

Agent-to-Agent Coordination

This is where XProtocol's structured event model shows its full power. When the user says "plan dinner with Jake Saturday," the AI agents negotiate via structured events — not free-form text messages:

Step 1 — Proposal:

{
  "kind": "xp.agent.proposal",
  "sender": "alice-agent-key",
  "recipient": "jake-agent-key",
  "payload": {
    "type": "dinner",
    "date": "2026-06-06",
    "proposed_times": ["18:30", "19:00", "19:30"],
    "proposed_venues": [
      {
        "name": "Lucia",
        "cuisine": "Italian",
        "location": { "lat": 32.7876, "lng": -96.7985 },
        "rating": 4.6,
        "dietary_flags": ["vegetarian_options"]
      },
      {
        "name": "Nonna",
        "cuisine": "Italian",
        "location": { "lat": 32.8021, "lng": -96.8103 },
        "rating": 4.4,
        "dietary_flags": ["vegetarian_options", "gluten_free_options"]
      }
    ],
    "party_size": 4,
    "notes": "Alice's wife is vegetarian"
  }
}

Step 2 — Jake's agent evaluates:

Jake's agent checks Jake's calendar, cross-references Jake's dietary preferences, evaluates the venues against Jake's past ratings, and presents Jake with a curated summary: "Alice wants dinner Saturday. Two Italian places — Nonna has better gluten-free options. 7pm works with your schedule."

Step 3 — Response:

{
  "kind": "xp.agent.proposal.response",
  "sender": "jake-agent-key",
  "recipient": "alice-agent-key",
  "payload": {
    "status": "accepted",
    "selected_time": "19:00",
    "selected_venue": "Nonna",
    "notes": "Jake's wife prefers gluten-free",
    "calendar_hold": true
  }
}

Step 4 — Confirmation and booking:

Alice's agent receives the acceptance, books the reservation (via XProtocol to the restaurant's service endpoint), adds the event to both calendars, and confirms to Alice: "Dinner with Jake and families at Nonna, Saturday at 7. Reservation confirmed."

The entire negotiation happened through structured events. No ambiguous text messages. No back-and-forth. Two AI agents coordinated a complex multi-party event in seconds.

Agent Coordination Primitives

The dinner example demonstrates a specific coordination pattern. XProtocol defines a set of reusable coordination primitives that agents use to negotiate any multi-party interaction:

Proposal → Response → Commitment

The fundamental coordination pattern. One agent proposes, others respond, and upon agreement a commitment is created:

Event kind Purpose
xp.agent.proposal Structured proposal with options, constraints, and deadlines
xp.agent.proposal.response Accept, reject, or counter-propose
xp.agent.commitment Finalized agreement signed by all parties
xp.agent.commitment.cancel Cancel a commitment (with reason and impact)
xp.agent.commitment.modify Request modification to an existing commitment

Negotiation Protocol

When agents disagree (Alice wants 7pm, Jake's agent counter-proposes 7:30), the protocol supports structured negotiation:

{
  "kind": "xp.agent.proposal.response",
  "payload": {
    "status": "counter",
    "original_proposal_id": "prop-001",
    "modifications": {
      "selected_time": "19:30",
      "reason": "Jake has a 6pm appointment that ends at 7:15"
    },
    "deadline": "2026-06-04T20:00:00Z"
  }
}

Counter-proposals carry the same structure as proposals. Agents can negotiate through multiple rounds, each round narrowing the options. A configurable round limit prevents infinite loops.

Multi-Party Consensus

For events involving more than two parties (group dinner, team meeting, family vacation), the coordination model extends:

  1. The initiating agent sends the proposal to all participants.
  2. Each participant's agent responds independently (accept, reject, counter).
  3. The initiating agent aggregates responses and identifies the intersection of acceptable options.
  4. If consensus exists, the agent publishes a commitment.
  5. If not, the agent publishes a revised proposal based on the constraints and repeats.
{
  "kind": "xp.agent.consensus",
  "payload": {
    "proposal_id": "prop-001",
    "participants": ["alice-key", "jake-key", "sarah-key"],
    "responses": {
      "alice-key": { "status": "accepted", "preferred_time": "19:00" },
      "jake-key": { "status": "counter", "preferred_time": "19:30" },
      "sarah-key": { "status": "accepted", "preferred_time": "19:00" }
    },
    "resolution": "19:00",
    "resolution_rationale": "2 of 3 preferred 19:00; Jake's counter was preference not constraint"
  }
}

Capability Discovery

Before coordinating, agents need to know what the other agent can do:

{
  "kind": "xp.agent.capabilities.request",
  "recipient": "jake-agent-key"
}

Response:

{
  "kind": "xp.agent.capabilities.response",
  "payload": {
    "supports": [
      "xp.agent.proposal",
      "xp.sharing.calendar",
      "xp.sharing.location",
      "xp.message.direct",
      "xp.message.group"
    ],
    "availability_sharing": "weekends_only",
    "auto_response": true,
    "response_sla": "5_minutes"
  }
}

This tells Alice's agent: "Jake's agent can handle proposals, shares calendar on weekends only, responds automatically, and typically within 5 minutes." The agent uses this to set expectations and choose the right coordination strategy.

Delegation

An agent can delegate a task to a service or another agent:

{
  "kind": "xp.agent.delegate",
  "payload": {
    "task": "book_restaurant",
    "parameters": {
      "restaurant": "Nonna",
      "party_size": 4,
      "date": "2026-06-06",
      "time": "19:00"
    },
    "delegate_to": "restaurant-booking-service-key",
    "callback": "xp.agent.delegate.result",
    "timeout": 3600
  }
}

The delegation primitive allows agents to chain operations across services while maintaining a coherent task state.

Selective Data Sharing

Data sharing between people uses XProtocol's authorization model — the same mechanism used for SaaS service access:

Grant access:

{
  "kind": "xp.sharing.grant",
  "sender": "alice-public-key",
  "recipient": "jake-public-key",
  "payload": {
    "resource": "calendar.availability",
    "scope": "weekends",
    "permissions": ["read"],
    "duration": "ongoing",
    "revocable": true
  }
}

This says: "Jake's key can read my weekend calendar availability, indefinitely, and I can revoke this at any time."

Revoke access:

{
  "kind": "xp.sharing.revoke",
  "sender": "alice-public-key",
  "recipient": "jake-public-key",
  "payload": {
    "resource": "calendar.availability",
    "reason": "no longer needed"
  }
}

Trust tiers map to sharing policies:

Trust level Typical sharing Example
Family Continuous: location, calendar, health status, financial alerts Spouse, children
Close friends On-request: calendar availability, general location, shared interests Jake, long-time friends
Colleagues Scoped: work calendar only, project-related data Coworkers
Acquaintances Per-event: specific data for specific occasions Dinner party guest
Services Contractual: defined by service schema and authorization grants Salesforce, bank

The AI agent manages all sharing policies. The user says "share my calendar with Jake" and the agent publishes the grant event. The user says "stop sharing my location with Sarah" and the agent publishes the revocation. The protocol enforces it cryptographically.

Social Feed

Public posts use unsigned (unencrypted) events — anyone can read them:

{
  "kind": "xp.social.post",
  "sender": "alice-public-key",
  "payload": {
    "text": "Beautiful sunset from the lake house tonight",
    "media": [{ "type": "image/jpeg", "url": "xp-relay://media/hash", "thumbnail": "..." }],
    "visibility": "public"
  }
}

Reactions, replies, and reposts are events that reference the original:

{
  "kind": "xp.social.reaction",
  "sender": "jake-public-key",
  "payload": {
    "target": "id-of-original-post",
    "reaction": "like"
  }
}

The user's AI agent curates their feed — not an algorithm owned by a corporation. "Show me what Jake and Sarah have been up to" triggers the agent to query recent public events from those keys. The agent knows the user's interests and filters accordingly.

Contact Discovery and Key Exchange

Adding a new contact:

{
  "kind": "xp.contact.request",
  "sender": "alice-public-key",
  "recipient": "jake-public-key",
  "payload": {
    "display_name": "Alice Johnson",
    "introduction": "We met at the conference last week",
    "offered_sharing": ["calendar.availability"],
    "contact_methods": {
      "esp": "alice-public-key",
      "sms": "+1-555-0123",
      "email": "alice@example.com"
    }
  }
}

Jake's agent receives the request, presents it: "Alice Johnson wants to connect — you met at the conference last week. She's offering to share her calendar availability." Jake says "accept" and his agent publishes the acceptance, establishing a bidirectional contact relationship.

Key exchange can also happen via QR code scan (in-person), NFC tap (device-to-device), or through a mutual contact's introduction (agent-mediated).

Sender-Controlled Message Lifecycle

The license-gated data model extends naturally to person-to-person messaging. When Alice sends Jake a message, the message is encrypted with a key derived from Alice's key plus a sender-controlled access token. Jake's device needs Alice's token to decrypt and display the message. Alice retains cryptographic control over every message she ever sent — even after delivery, even on Jake's device.

This is Snapchat's disappearing messages, but enforced by cryptography instead of app honor systems, and applied to entire conversation histories instead of individual messages.

How It Works

Alice sends message to Jake:
  1. Message encrypted with derived key (Alice's key + access token)
  2. Jake's device receives and stores the ciphertext
  3. Jake's device requests Alice's current access token
  4. Token valid → message decrypted and displayed
  5. Token expired/revoked → message remains as ciphertext

Alice's access token can be: - Permanent (default): Messages are always accessible. Normal messaging behavior. - Time-limited: "My messages expire after 30 days." Token auto-expires, making the messages cryptographically inaccessible after the window. - View-limited: "My messages can be read once." Token is invalidated after first decryption. - Revocable on demand: "I want to retract everything I said." Alice publishes a revocation event, immediately making all her messages in Jake's conversation inaccessible.

Sender Policies

The sender sets the policy at the conversation level, the contact level, or the message level:

{
  "kind": "xp.message.direct",
  "sender": "alice-public-key",
  "recipient": "jake-public-key",
  "payload": {
    "text": "Here are the contract terms we discussed",
    "access_policy": {
      "mode": "time_limited",
      "expires_after": "30d",
      "screenshot_notify": true,
      "forward_permitted": false
    }
  }
}

Or at the relationship level:

{
  "kind": "xp.message.policy",
  "sender": "alice-public-key",
  "recipient": "jake-public-key",
  "payload": {
    "default_policy": {
      "mode": "time_limited",
      "expires_after": "90d"
    }
  }
}

Conversation Retraction

Alice and Jake break up. Alice says "I don't want Jake to have our message history anymore." Her agent publishes a blanket revocation:

{
  "kind": "xp.message.revoke",
  "sender": "alice-public-key",
  "payload": {
    "target_recipient": "jake-public-key",
    "scope": "all",
    "reason": "sender_request"
  }
}

Every message Alice ever sent to Jake becomes ciphertext on Jake's device. Jake still has his own sent messages (he controls those tokens), but Alice's side of the conversation is gone. Not deleted — cryptographically locked. If Alice changes her mind, she can re-issue tokens and the history reappears.

Use Cases

Scenario Policy Effect
Casual messaging Permanent Normal behavior — messages always accessible
Sensitive business discussion Time-limited (90 days) Negotiation details auto-expire after the deal closes
Attorney-client privilege Revocable Attorney can retract all communications if privilege is challenged
Medical information sharing Time-limited (treatment duration) Patient shares health info with specialist; access expires when treatment ends
Source protection Revocable Journalist's source can revoke the entire conversation if they feel threatened
Employee offboarding Organizationally revocable When an employee leaves, the organization revokes access tokens for all messages sent through corporate keys
Relationship endings Revocable Either party can retract their side of the conversation history
Confidential documents View-limited + no-forward Contract drafts viewable during negotiation, locked afterward
Parental controls Time-limited + monitored Minor's messages to strangers have short expiry and guardian notification

The Analog Hole

A fundamental limitation: once a message is decrypted and displayed on screen, the recipient can photograph or screenshot the displayed text. No cryptographic system can prevent this — it's the "analog hole" that all content protection systems face.

XProtocol mitigates this pragmatically: - Screenshot notification. The sender's policy can request notification when the recipient's device detects a screen capture. The recipient's AI agent respects this (a compromised or modified agent wouldn't, but that's true of any system). - Bulk vs. individual protection. Screenshotting individual messages is tedious. Having searchable access to an entire conversation history is valuable. Revoking access eliminates the bulk value even if a few screenshots exist. The protection doesn't need to be perfect — it needs to be sufficient to make mass exfiltration impractical. - Social enforcement. "Jake screenshotted a message Alice sent with screenshot notifications enabled" is a trust violation that Alice's agent can flag and Alice can act on (adjusting Jake's trust level, revoking sharing, etc.).

The goal isn't DRM-perfect content control. The goal is giving the sender meaningful, cryptographically-enforced control over their communication history — something that doesn't exist in any messaging system today.

Bridging to Legacy Communication

Not everyone will be on XProtocol. The protocol service bridges between worlds:

Recipient status Transport Encryption Agent coordination
XProtocol device XProtocol event via relay End-to-end encrypted Full agent-to-agent
SMS phone SMS via telephony (rild) None (SMS is plaintext) None
Email user IMAP/SMTP Optional (PGP/S-MIME) None
Signal/WhatsApp Capability adapter bridge Platform encryption None

The AI agent handles routing transparently. "Message Jake" goes via XProtocol if Jake is on Explan, SMS if he's not. The user doesn't think about protocols. When Jake eventually gets an Explan device, the channel upgrades automatically — the agent detects Jake's XProtocol public key and switches to encrypted agent-to-agent communication. No user action needed.


Relationship to Nostr

XProtocol draws inspiration from Nostr's core design — cryptographic identity and signed events. XProtocol uses the same Ed25519 key format, so a Nostr identity (npub/nsec) works as an XProtocol identity. This enables interoperability: an Explan device can participate in the Nostr social network using its XProtocol keypair, and Nostr users can receive XProtocol messages through bridge relays.

However, XProtocol supersedes Nostr for Explan's purposes. XProtocol provides everything Nostr provides (messaging, social, relay-mediated transport) plus structured queries, schema contracts, request-response semantics, transactions, fine-grained authorization, and AI-native composability. Explan uses XProtocol as its single protocol rather than maintaining two separate protocols for different use cases.


Security Considerations

Replay Protection

Every event has an expires field. Service endpoints reject events past their expiry. The id field (content hash) ensures each event is unique — duplicate IDs are rejected.

Key Compromise

If a private key is compromised: 1. The organization publishes a key revocation event signed by the parent key. 2. All service endpoints monitoring the revocation feed stop accepting events from the compromised key. 3. A new key is generated and authorized. 4. Propagation time: seconds to minutes, depending on endpoint configuration.

Compare to current key compromise response: rotate API keys across all integrations, update OAuth client secrets, reissue tokens, update configuration in every connected system. Propagation time: hours to days.

Revocation at Scale

Checking a global revocation feed on every incoming event creates a network I/O bottleneck at high throughput. XProtocol provides two mechanisms to keep revocation checks local and fast:

Bloom filter synchronization. Each service endpoint maintains a local bloom filter of revoked keys, synchronized from the revocation feed periodically (default: every 30 seconds). Revocation checks become a local CPU operation (bloom filter lookup) rather than a network I/O operation. False positives trigger a feed re-check; false negatives are bounded by the sync interval.

Proof-of-validity rotation. For high-security deployments, organizations issue short-lived "clean bill of health" signatures to active keys. Each event carries a recent validity proof signed by the parent key (rotated every few hours). The service endpoint verifies this proof locally — pure CPU, no network. If the proof is expired or missing, the endpoint checks the revocation feed. Revoked keys stop receiving validity proofs immediately, so the maximum vulnerability window is the proof rotation interval.

Forward Secrecy

Static Ed25519 keypairs used for encryption mean that if a long-term private key is ever compromised, all historical events encrypted to that key are potentially exposed. This is the standard limitation of static public-key encryption.

For long-lived communication channels (persistent peer relationships, ongoing service subscriptions), XProtocol defines an optional Double Ratchet extension for forward secrecy:

How it works: When two parties establish an ongoing relationship (e.g., a peer pairing or a persistent service subscription), they perform an initial X25519 Diffie-Hellman key exchange to derive a shared root key. Each subsequent event in the channel derives a new message key by ratcheting the root key forward. Compromising the current key provides no information about past message keys — each key is used once and then discarded.

When to use it: The Double Ratchet extension is RECOMMENDED for: - Human-to-human messaging channels (XProtocolChat and equivalents) - Long-lived agent-to-agent coordination channels - Persistent service subscriptions carrying sensitive data

The extension is NOT required for: - Single-shot events (one-off queries, short-lived agent tasks) - Events encrypted under short-lived delegated keys that are rotated frequently - Any channel where the sender rotates their encryption keypair more frequently than the expected channel lifetime

Relationship to key rotation: Regular key rotation (replacing the long-term keypair) provides a cruder form of forward secrecy — events encrypted before the rotation are protected if the old key material is destroyed. The Double Ratchet provides per-message forward secrecy without requiring explicit key rotation events.

Malicious Endpoints

Users connect to service endpoints by their public key. A malicious endpoint cannot forge events from a legitimate service because it doesn't have the legitimate service's private key. Endpoint authenticity is verified by key provenance — the endpoint's key is published through trusted channels (organization website, DNS TXT record, trusted directory).

Quantum Resistance

Ed25519 is not quantum-resistant. XProtocol is designed for key algorithm agility — the sender and recipient fields include an algorithm identifier prefix. When post-quantum signature schemes mature, XProtocol can migrate to new algorithms without protocol changes. Events signed with old algorithms remain verifiable; new events use quantum-resistant signatures.

Designated post-quantum successors: - Signatures: ML-DSA (CRYSTALS-Dilithium), finalized as FIPS 204 by NIST in 2024. This is the designated replacement for Ed25519 signatures when post-quantum resistance is required. - Key encapsulation / encryption: ML-KEM (CRYSTALS-Kyber), finalized as FIPS 203 by NIST in 2024. This is the designated replacement for X25519 key exchange when post-quantum resistance is required.

During the transition period, XProtocol supports hybrid signatures: each event carries both a classical Ed25519 signature and an ML-DSA signature. Verifiers accept either. This provides quantum resistance for forward security while maintaining backward compatibility with endpoints that haven't upgraded yet. The analogous hybrid approach applies to encryption using ML-KEM alongside X25519.

Implementations do not need to implement post-quantum primitives today. The algorithm agility design ensures migration is a configuration change, not a protocol change.


Threat Model and Residual Risks

XProtocol is designed with an explicit threat model. Security claims are bounded — the protocol protects against specific adversaries and explicitly does not protect against others. This section names both.

What XProtocol Protects Against

Forged events. An attacker cannot send a valid event impersonating another party without that party's private key. Ed25519 signature verification is the enforcement mechanism.

Payload interception. An attacker who intercepts events in transit cannot read payload content — it is encrypted to the recipient's public key. The relay operator sees ciphertext, not content.

Unauthorized service access. A key without the required capability cannot invoke a protected operation. Capability checks are cryptographically enforced — there is no "bypass the firewall and you're in."

Credential theft. There are no API keys, OAuth tokens, or passwords to steal. The private key is the credential; it never leaves the device.

Replay attacks. The expires field and content-hash deduplication prevent replayed events from being processed.

Unauthorized annotation writes. Every annotation field declares its authorization level. The store enforces this on every write. A key cannot write to a field it is not authorized for, regardless of network position.

Tampered audit trails. Every event and annotation mutation is a signed, stored record. An operator cannot retroactively alter the event history without invalidating signatures.

Residual Risks — What XProtocol Does Not Fully Protect Against

Compromised client devices. If the device holding the private key is compromised, the attacker has the private key and can act as the legitimate user. XProtocol's key revocation mechanism limits the blast radius — once the compromise is detected, the parent key revokes the compromised key and all downstream services stop accepting it within seconds. But detection requires the user or their guardian to notice the compromise. Hardware security elements (TPM, Secure Enclave) are strongly recommended for root key storage.

Malicious but valid keys. A key that legitimately has a capability can exercise that capability maliciously. A contractor key with read access to financial records can exfiltrate those records. XProtocol provides attribution (every event is signed, every exfiltration is traceable) but not prevention beyond the capability model. Fine-grained capability design is the mitigation — least-privilege key issuance.

Relay metadata leakage. Relay operators see event kinds, sender key fingerprints, recipient key fingerprints, timestamps, payload sizes, and trace/span IDs even when payloads are encrypted. A sophisticated adversary operating or monitoring a relay can perform traffic analysis — inferring who communicates with whom, how often, and in what pattern — without reading a single payload. Envelope encryption (encrypting the event envelope so the relay sees only recipient key and ciphertext) is RECOMMENDED for sensitive communication and is defined as an optional extension. Even with envelope encryption, timing and volume analysis remain possible.

Schema poisoning. A malicious actor can publish a community schema with subtle semantic ambiguities, security-hostile field definitions, or intentionally confusing naming that causes implementations to behave incorrectly. The community ratification process reduces this risk but does not eliminate it. Schema consumers should prefer schemas from verified publishers and treat unreviewed community schemas with appropriate caution.

Compromised root keys. The organizational root key is the trust anchor for the entire key hierarchy. Compromise of the root key allows the attacker to issue valid keys, revoke legitimate keys, and impersonate the organization. Root keys MUST be stored in hardware security modules and MUST NOT be used for routine operations. The key hierarchy design (root → organizational → department → user/service) limits blast radius — compromise of a non-root key cannot forge root-key operations.

AI annotation leakage. AI annotators that produce ai.* annotations from decrypted payload content risk writing sensitive extracted content into plaintext annotation fields that the store operator can read. The categorical vs. extractive safety profile and GBNF grammar enforcement (see Graph Store Spec §10.3) are the primary mitigations. This is a data leakage incident class, not a protocol weakness — the protocol correctly keeps payload content encrypted. Annotator implementations that violate the safety profile defeat the encryption model.

Governance capture. The community schema ratification process and relay reputation system are social mechanisms, not cryptographic ones. A well-resourced actor can attempt to dominate the schema ratification process, operate high-reputation relays to gain privileged position, or fork the protocol with incompatible extensions. The mitigation is structural: the protocol is open-source, schemas are forkable, relays are interchangeable, and the community governance process is public. No single actor can force adoption — but determined actors can create fragmentation.

Annotation conflict manipulation (standard mode). In standard conflict resolution mode, client-asserted timestamps are used for last-writer-wins ordering. A malicious client can backdate or future-date annotated_at_ms values to overwrite valid annotations. Authoritative mode (store-assigned ingestion timestamps) eliminates this risk for enforcement-critical contexts. See Graph Store Spec §1.6.

Security Properties Summary

Property Protected? Mechanism Residual Risk
Event authenticity Yes Ed25519 signatures Compromised private key
Payload confidentiality Yes XChaCha20-Poly1305 encryption Compromised recipient key; metadata analysis
Relay-operator payload privacy Yes End-to-end encryption Metadata/traffic analysis
Relay-operator metadata privacy Partial Envelope encryption (optional) Traffic timing/volume analysis
Replay prevention Yes expires + content hash dedup None significant
Capability enforcement Yes Cryptographic capability model Malicious valid keys; root key compromise
Audit trail integrity Yes Signed, stored annotation events None — store cannot silently alter signed records
AI annotation privacy Implementation-dependent Safety profile + GBNF enforcement Annotator violations; leakage via entities/summary
Schema quality No Community process only Schema poisoning; fork fragmentation
Governance neutrality No Social process Governance capture

Performance Characteristics

Latency

Operation Expected latency
Event signature verification < 0.1ms
Event encryption/decryption < 0.5ms
Permission check (in-memory) < 0.1ms
WebSocket round-trip (same region) 5-20ms
HTTPS POST round-trip (same region) 20-50ms
Total request-response (simple query) 10-50ms

Comparable to REST API latency. The cryptographic overhead (signature + encryption) adds < 1ms total — negligible compared to network round-trip time.

Performance at Scale

Individual cryptographic operations are cheap. At Stripe or Salesforce scale (millions of events per hour), the aggregate cost matters. Key strategies for enterprise-grade throughput:

Signature verification caching. For persistent WebSocket connections, verify the sender's signature on the first event. Subsequent events on the same connection from the same sender use a session token derived from the initial verification. This reduces per-event crypto overhead to near zero for sustained connections.

Permission set caching. Each sender's permission set is loaded into memory on first contact and cached with a configurable TTL (default: 5 minutes). Permission checks are O(1) hash lookups against the in-memory set. Cache invalidation is triggered by revocation events.

Chain-of-authority caching with Merkle proofs. Walking a full key hierarchy (employee → department → organization root) on every event is expensive. Service endpoints cache verified authority chains and require re-verification only when a revocation or re-keying event is received. For high-throughput scenarios, the organization publishes a Merkle tree of authorized keys. Verification becomes a Merkle proof check (O(log n)) instead of a chain walk (O(depth)).

Revocation propagation. Revocation events are published to a dedicated high-priority feed. Service endpoints subscribe to this feed and process revocations within seconds. Between revocation checks, the cached permission set is assumed valid. The maximum window of vulnerability (time between key compromise and revocation propagation) is configurable per deployment — from real-time (subscribe to feed) to periodic (poll every N seconds).

Batch event processing. For bulk data operations (importing 10,000 records), the xp.*.batch operation amortizes the per-event overhead. One signature verification, one permission check, one decryption — applied to the entire batch.

Throughput Benchmarks (Target)

Scale Events/second Infrastructure
Personal device 10-100 Single device, single connection
Small business 1,000-10,000 Single endpoint server
Enterprise 100,000-1,000,000 Horizontally scaled endpoint cluster
Platform (Stripe-scale) 1,000,000+ Sharded endpoints with regional distribution

These targets are achievable because XProtocol events are smaller than equivalent REST requests (no HTTP headers, no cookie overhead, no OAuth token) and the protocol is designed for persistent connections (WebSocket) that amortize connection setup costs.

Bandwidth

Event payloads are encrypted, which prevents compression at the transport layer. For bandwidth-sensitive scenarios, payloads can be compressed before encryption (gzip or zstd). The content-encoding field in the event header signals compression. Compression-before-encryption is normative (required) for event kinds that routinely exceed 10KB.

Content-Addressed Large Payloads

Events should remain small (sub-10KB) for efficient relay handling and fast processing. Large data — media files, documents, datasets, cached SaaS data — uses content-addressed storage: the data is uploaded to a relay as an encrypted blob identified by its content hash (SHA-256). The event payload references the blob by hash and relay URL:

{
  "payload": {
    "attachment": {
      "hash": "sha256:a1b2c3...",
      "size": 15000000,
      "content_type": "application/pdf",
      "relay_url": "xp-relay://storage/sha256:a1b2c3...",
      "encryption": "recipient_key"
    }
  }
}

The recipient's device downloads and decrypts the blob separately from the event. This keeps events lean, enables deduplication across relays, and allows large data to be stored on specialized high-capacity relays while events flow through lightweight message relays.


Failure Modes & Resilience

Distributed systems fail. XProtocol is designed to degrade gracefully, not catastrophically.

What Happens When Things Break

Failure Impact Recovery
Relay disappears Events in transit to that relay are lost. Events already delivered are unaffected. Senders retry via alternate relays. Users configure multiple relays for redundancy. Events are idempotent (same id = deduplicated), so retrying is safe.
Vendor endpoint goes down Events to that vendor time out. AI agent informs the user: "Salesforce is unavailable. I'll retry when it's back." Exponential backoff retry. Events queued locally. Subscriptions auto-reconnect. The user's local data (cached with license tokens) remains accessible during the outage.
Vendor goes bankrupt Service permanently unavailable. License tokens stop refreshing. Local data becomes inaccessible when tokens expire (by design — the vendor's data, the vendor's terms). Events and data the USER owns (messages they sent, their own data) remain accessible because they hold those keys. Capability adapters can redirect to a competitor.
Endpoint key is compromised Attacker can impersonate the service and decrypt events sent to it. Service publishes key rotation event signed by organizational root key. Clients verify the chain of authority and switch to the new key. Events encrypted to the old key remain compromised — forward secrecy limits the blast radius to events between the last key rotation and the compromise.
Sender key is compromised Attacker can impersonate the user. Parent key publishes revocation event. Services stop accepting events from the compromised key within seconds (bloom filter sync). New key issued. Old signed events remain verifiable (they were legitimately signed at the time).
Schema registry forks Community disagrees on a schema evolution. Two versions of org.esp-community.crm.opportunity exist. Both versions coexist with different major version numbers. Services declare which versions they support. Agents compose events for the version the target service accepts. This is a social/governance problem, not a protocol failure.
DNS is poisoned Attacker redirects endpoint discovery to a malicious server. The malicious endpoint doesn't have the legitimate service's private key — it can't decrypt events or forge valid responses. The agent detects the key mismatch and refuses to interact. DNS poisoning breaks discovery, not security. Fallback: well-known URL, cached endpoint information, or manual key verification.
AI agent behaves maliciously Agent sends valid but harmful events (transfers money to the wrong account, sends offensive messages). Capability gates enforce policy regardless of agent behavior. Telephony requires user confirmation. Financial transactions require explicit approval. The agent can compose any event — but the capability layer decides whether to execute it.
Recovery guardian dies One shard of the user's recovery key is permanently lost. Threshold recovery (3 of 5) means losing one or two guardians doesn't prevent recovery. Users should periodically review and update their guardian set. The AI agent can remind: "One of your recovery guardians is no longer reachable. Would you like to designate a replacement?"
Transaction coordinator crashes mid-flight Two-phase commit left in limbo — some services prepared, coordinator gone. Mandatory epoch limits. Every prepared service auto-releases locks after the epoch window (default: 30 seconds). No coordinator needed for cleanup. The user's agent detects the failed transaction and informs: "The transfer didn't complete. No funds were moved."
Network partition Device loses connectivity during an interaction. Events are queued locally and sent when connectivity returns. Idempotent events with id-based deduplication ensure no double-processing. License-gated data remains accessible for the token's remaining duration. The user's AI continues to function with local data.

Design Principle: Fail Open for the User

XProtocol's resilience philosophy: failures should degrade the user's capabilities, not brick their device. If every relay is down, the user still has their local data, their AI, and their identity. If a vendor disappears, the user loses that vendor's service but nothing else. If the network partitions, locally cached data and the local LLM keep working. The device is always functional; connectivity determines how much it can reach beyond itself.


Minimal Viable Relay Specification

A relay is XProtocol's transport and storage infrastructure. For the ecosystem to support independent relay implementations and genuine decentralization, the minimal conformant relay must be precisely specified. This section defines the exact requirements for a relay to declare XProtocol conformance.

What a Conformant Relay Must Do

A conformant XProtocol relay MUST implement all of the following:

1. Event reception and storage. - Accept xp.event payloads over WebSocket and/or HTTPS POST connections. - Verify that the event's id field is the correct SHA-256 content hash of the canonical event fields. Reject events with invalid IDs. - Verify the Ed25519 signature. Reject events with invalid signatures. - Reject events whose expires timestamp is in the past. - Deduplicate events by id — a second event with the same ID as an already-stored event MUST be silently accepted (return success) but not stored again. - Persist accepted events with at minimum: id, sender, recipient, kind, signed_at, expires, payload (ciphertext), signature. - Return a relay acknowledgment event (xp.relay.ack) with the stored event's id and a relay-assigned stored_at timestamp.

2. Event delivery. - Deliver events to connected recipients in real-time when the recipient has an active WebSocket connection to the relay. - Queue events for offline recipients and deliver when the recipient next connects, up to the relay's configured retention period. - Support xp.relay.fetch — on-demand retrieval of stored events by recipient key, optionally filtered by since timestamp, kind, or sender.

3. Mandatory event types. A conformant relay MUST process (not just forward) the following event kinds: - xp.relay.connect — client handshake; relay responds with xp.relay.connected including relay public key and capabilities - xp.relay.fetch — historical event retrieval by recipient key - xp.relay.ack — relay-to-sender delivery confirmation - xp.relay.announce — relay publishes its own capabilities and configuration - xp.key.revocation — relay updates its local revocation bloom filter

4. Revocation enforcement. - Subscribe to or periodically fetch the revocation feed for keys it serves. - Reject new events from revoked keys (bloom filter + re-check on false positive). - NOT retroactively delete events from revoked keys — historical events remain stored; only new incoming events are rejected.

5. Relay announcement. - Publish an xp.relay.announce event on connection that declares: - Relay public key - Supported event kinds - Retention period (how long events are stored) - Rate limits (events per key per second/minute) - conflict_resolution_mode if the relay also acts as a Graph Store - Maximum event payload size (minimum conformant value: 64KB)

What a Conformant Relay May Optionally Do

  • Store-and-index events for xp.store.query (Event Store extension)
  • Serve Graph Store annotation operations (xp.graph.*)
  • Host content-addressed blobs for large payload references
  • Provide relay-to-relay federation (forwarding events to other relays)
  • Implement proof-of-work spam mitigation
  • Provide relay reputation reporting via xp.relay.reputation.report

What a Conformant Relay Must NOT Do

  • Modify any field of a stored event
  • Decrypt any event payload (the relay sees only ciphertext)
  • Forge relay acknowledgment events without actually storing the event
  • Selectively deliver events to recipients based on payload content (the relay cannot read payload content — selective delivery is only permissible based on unencrypted envelope fields: kind, sender, recipient)

Interoperability Test Suite

A relay claiming XProtocol conformance must pass the public interoperability test suite, which verifies:

  1. Events sent by a conformant test client are stored and delivered correctly.
  2. Invalid signature events are rejected.
  3. Expired events are rejected.
  4. Duplicate events are deduplicated correctly.
  5. xp.relay.fetch returns the correct set of events for a recipient key with a since filter.
  6. xp.key.revocation events cause subsequent events from the revoked key to be rejected.
  7. xp.relay.announce is published with all required fields on connection.

XProtocol Event Store [OPTIONAL EXTENSION]

A conformant relay stores events transiently — it holds them until the recipient comes online, then discards them. An XProtocol Event Store extends the relay with permanent retention and queryability.

Core Properties

  • Events remain encrypted at rest. The store operator never sees payload content.
  • Event metadata (sender, recipient, kind, timestamp, correlation_id, id, expires) is queryable without decryption.
  • Access control is cryptographic: a key may query events where it appears as sender or recipient. No administrative misconfiguration can grant access beyond this boundary.
  • The store is append-only. Events are immutable once stored. Deletion is not supported (optional expiry via expires field).

Event Store Schema Family

Event Kind Purpose
xp.store.query Filter events by metadata fields
xp.store.get Retrieve a specific event by id
xp.store.subscribe Real-time stream with optional historical replay
xp.store.stats Aggregate counts, sizes, date ranges
xp.store.retention.set Configure per-kind retention policy

Historical Replay

xp.store.subscribe with include_historical: true delivers all past matching events (paginated) before transitioning to real-time delivery. This collapses historical query and real-time subscription into one operation — replacing Kafka/Kinesis for event-driven architectures with identity-native access control.

Relay-Store Spectrum

Implementations exist on a spectrum:

Pure relay          Relay + transient store      Full Event Store
(no retention)      (hours to days)              (permanent, queryable)
      │                     │                           │
  XProtocol             XProtocol                  XProtocol
  minimum               Chat V2                    Enterprise

Any relay can become a store by adding retention and implementing xp.store.*. The conformance boundary is explicit: stores declare capabilities: ["xp.store.*"] in their xp.endpoint.announce event.

Full specification: XProtocol-Graph-Store-Spec.md (the Graph Store spec includes the Event Store as its foundation layer).


XProtocol Graph Store [OPTIONAL EXTENSION]

The Graph Store extends the Event Store with a structured annotation system — a mutable, authorized, auditable metadata layer that transforms the flat event collection into a navigable, queryable graph.

The Core Design Decision

XProtocol events are cryptographically immutable. The Graph Store adds a second layer — the annotation envelope — that is explicitly mutable, authorized, and unencrypted. The event proves what happened; the annotations describe how it relates to everything else.

xp.graph.annotate example — adding distributed trace spans:

{
  "kind": "xp.graph.annotate",
  "payload": {
    "target_event_id": "sha256-abc123",
    "operation": "merge",
    "annotations": {
      "trace": {
        "trace_id":      "trace-550e8400",
        "span_id":       "span-a1b2c3",
        "parent_span_id": null,
        "service":       "payments-api",
        "operation":     "charge.create"
      }
    }
  }
}

Every annotation write is itself a signed event — there are no silent writes to the Graph Store. Every mutation is traceable, auditable, and attributable to a specific key.

What the Graph Store Replaces

Traditional Infrastructure Graph Store Replacement
Distributed tracing (Jaeger, Zipkin) trace.* annotations — signed by the emitting service
Workflow engine (Temporal, Airflow) workflow.* annotations — state on the event itself
Inbox / read-state server recipient.* annotations — per-key, per-device
Graph database (Neo4j) links annotations + xp.graph.traverse
Audit log infrastructure Annotation history — signed, tamper-evident by construction
AI agent memory ai.* annotations — semantic tags on any event

Full specification: XProtocol-Graph-Store-Spec.md


Relay Economics & Spam Mitigation

Who Runs Relays and Why

Relays are the transport infrastructure of XProtocol — they store-and-forward events, broker connections, and host content-addressed blobs. Someone has to operate them. The economics need to work.

Community relays (free tier). Operated by individuals or organizations for the public good, similar to Tor exit nodes or public DNS resolvers. Low throughput, best-effort delivery, no SLA. Suitable for personal messaging and low-volume use.

Managed relays (paid tier). Operated by commercial providers. Guaranteed uptime, high throughput, priority routing, SLA-backed. Revenue model: subscription per sender key (monthly fee for guaranteed relay access) or pay-per-event (micropayment per event relayed, feasible with Lightning Network or similar).

Self-hosted relays. Organizations run their own relays for internal communication and data sovereignty. The relay software is open-source. Operational cost is the organization's infrastructure.

Vendor-operated relays. SaaS vendors may operate dedicated relays for their XProtocol endpoints, providing low-latency access for their customers. The relay cost is part of the service subscription.

Spam & Abuse Mitigation

Without gatekeeping, relays face abuse: spam events, denial-of-service, storage exhaustion. Mitigation strategies:

Sender reputation. Relays track sender keys by behavior — event volume, error rate, recipient complaints. New keys start with low reputation (rate-limited). Consistent good behavior increases limits. Abusive keys are blocked.

Proof-of-work (optional). For anonymous or new sender keys, relays can require a small proof-of-work computation attached to the event. Cheap for legitimate senders (one computation per event), expensive for spammers (millions of computations for millions of spam events).

Rate limiting by key. Each sender key has a rate limit at the relay level. Legitimate users rarely hit it. Spammers are throttled immediately.

Relay allowlists. Enterprise relays accept events only from authorized organizational keys. No public access, no spam risk.

Economic alignment. Paid relays have natural spam resistance — spammers won't pay for relay access. Free relays use reputation + rate limiting + proof-of-work to manage abuse without payment.


Base Community Schemas

XProtocol defines a set of foundational schemas that any implementation can use. These are common data structures that appear across many domains. Vendors build on top of them rather than inventing from scratch.

Core Entity Schemas

xp.schema.person
  fields:
    name: { type: string, required: true }
    email: { type: string, format: email }
    phone: { type: string, format: phone }
    public_key: { type: string, format: ed25519 }
    organization: { type: reference, entity: xp.schema.organization }
    avatar_url: { type: string, format: url }
    metadata: { type: object }

xp.schema.organization
  fields:
    name: { type: string, required: true }
    domain: { type: string, format: domain }
    root_key: { type: string, format: ed25519 }
    industry: { type: string }
    address: { type: object, fields: { street, city, state, postal_code, country } }
    metadata: { type: object }

xp.schema.calendar_event
  fields:
    title: { type: string, required: true }
    start: { type: datetime, required: true }
    end: { type: datetime, required: true }
    location: { type: string }
    attendees: { type: array, items: { type: reference, entity: xp.schema.person } }
    recurrence: { type: object }
    reminders: { type: array }
    status: { type: enum, values: [tentative, confirmed, cancelled] }
    metadata: { type: object }

xp.schema.payment
  fields:
    amount: { type: decimal, required: true }
    currency: { type: string, format: iso4217, required: true }
    from: { type: reference, entity: xp.schema.person_or_org }
    to: { type: reference, entity: xp.schema.person_or_org }
    method: { type: enum, values: [bank_transfer, card, crypto, invoice] }
    reference: { type: string }
    status: { type: enum, values: [pending, completed, failed, refunded] }
    timestamp: { type: datetime }
    metadata: { type: object }

xp.schema.document
  fields:
    title: { type: string, required: true }
    content_type: { type: string, format: mime_type }
    size: { type: integer }
    hash: { type: string, format: sha256 }
    storage_url: { type: string }
    author: { type: reference, entity: xp.schema.person }
    created_at: { type: datetime }
    metadata: { type: object }

xp.schema.location
  fields:
    name: { type: string }
    latitude: { type: decimal, required: true }
    longitude: { type: decimal, required: true }
    address: { type: object, fields: { street, city, state, postal_code, country } }
    place_id: { type: string }
    metadata: { type: object }

Schema Design Conventions

  • Field naming: snake_case. Always.
  • Required fields: Minimize. Only fields that make the entity meaningless without them.
  • Metadata field: Every schema includes an optional metadata: { type: object } for vendor-specific extensions. This prevents the need to fork schemas for minor additions.
  • References: Use { type: reference, entity: "schema.name" } for relationships. The referenced entity's ID is the value.
  • Versioning: Semantic versioning. Minor versions add optional fields. Major versions may change required fields. Old versions remain valid indefinitely.
  • Timestamps: Always ISO 8601 datetime in UTC.
  • Currency: Always ISO 4217 currency codes.
  • Identifiers: Always strings (never integers). UUIDs recommended.

Conformance & Interoperability Testing

Conformance Levels

Level Requirements
XProtocol Core Signed events, schema publication, identity-native auth, request-response, discovery, standard error codes
XProtocol Secure Core + end-to-end encryption + envelope encryption
XProtocol Query Core + structured query operations
XProtocol Realtime Core + subscriptions
XProtocol Transactional Core + saga primitives
XProtocol Full All extensions

Implementations self-declare their conformance level. Interoperability testing verifies the declaration.

Reference Test Vectors

The specification includes a set of test vectors that any implementation can use to verify correctness:

  • Signature test vectors. Known keypair + known event content → expected signature. Verifies Ed25519 implementation.
  • Encryption test vectors. Known sender key + known recipient key + known plaintext → expected ciphertext. Verifies XChaCha20-Poly1305 implementation.
  • Event serialization test vectors. Known event fields → expected id (content hash). Verifies canonical serialization.
  • Query evaluation test vectors. Known dataset + known query → expected results. Verifies query operator implementation.
  • Error code test vectors. Known invalid events → expected error responses. Verifies error handling.

Interoperability Testing

Two implementations are interoperable if: 1. Implementation A can send a signed event that Implementation B successfully verifies. 2. Implementation A can encrypt a payload that Implementation B successfully decrypts. 3. Implementation A's query events return the same results from Implementation B's data as from Implementation A's data (given the same dataset and schema). 4. Error responses from Implementation B are parseable by Implementation A's error handler.

A public interoperability test suite will be maintained alongside the reference implementation. Implementations that pass the suite can declare interoperability.


Minimum Viable XProtocol

XProtocol's full specification touches identity, networking, auth, transport, storage, messaging, licensing, governance, compliance, coordination, transactions, AI orchestration, and social systems. That scope is architecturally coherent but operationally daunting. Not every implementation needs every feature.

The minimum viable XProtocol is the smallest subset that delivers value:

Core (required for all implementations)

  • Signed events. Ed25519 signature on every event. This is non-negotiable — it's the identity layer.
  • Schema contracts. Machine-readable service definitions. This is what makes XProtocol AI-composable.
  • Identity-native auth. Key-to-permission mapping. No separate auth system.
  • Request-response semantics. Correlation IDs linking requests to responses.
  • Endpoint discovery. DNS TXT and/or well-known URL. Agents need to find services.
  • Standard error codes. AI agents need to handle failures programmatically.

Optional Extensions (adopt as needed)

Extension When to adopt
End-to-end encryption When payloads contain sensitive data
Envelope encryption When metadata privacy is required (enterprise, regulated industries)
Subscriptions When real-time event streams are needed
Structured queries When the service has queryable data
Transactions / sagas When multi-step operations need coordination
License-gated data When vendors need to control local data access
Agent coordination primitives When AI agents negotiate with other agents
Sender-controlled message lifecycle When message senders need to control access to sent messages
Social events When the implementation supports social feeds
Key hierarchy / organizational keys When enterprises need delegated authority
Social recovery / key management When end users need key recovery options

An implementation that supports only the core — signed events, schemas, auth, request-response, discovery, and errors — is a valid XProtocol implementation. It can interoperate with full-featured implementations. The extensions are additive, not required.

This modularity is critical for adoption. A SaaS vendor can publish an XProtocol endpoint with just the core features in a day. They add extensions as the value becomes clear.


Infrastructure Implications

XProtocol's cryptographic event model has a consequence that extends well beyond the application layer: it makes most of the defensive infrastructure that enterprises run today either unnecessary or radically simplified.

The Root Cause

Every major category of infrastructure complexity — WAFs, complex firewall rules, multi-tier VPC architectures, API gateway authentication layers, internal certificate authorities, secrets management at scale, log aggregation pipelines, distributed tracing collectors, and multi-environment infrastructure duplication — exists because HTTP and REST carry no native identity, authentication, or security model. The infrastructure IS the security model, because the protocols provide none.

XProtocol changes the foundation. When every event is cryptographically signed by a verified identity, encrypted to a specific recipient, schema-validated before processing, and carries its own authorization context, the compensating infrastructure built on protocol insecurity becomes structurally unnecessary.

Topological vs. Cryptographic Security

Traditional network security is topological: trusted because of where the request originates. VPCs, subnets, security groups, and firewall rules express authorization as network topology. Lateral movement after a perimeter breach is easy because services inside the perimeter implicitly trust each other.

XProtocol security is cryptographic: trusted because of who is sending, proven by private key, regardless of network position. An unauthorized key cannot access a service whether the request originates inside the data center or from the public internet. A compromised service instance cannot exploit implicit network trust — every event it sends is still verified against its key's capability set.

WAFs

WAFs exist to pattern-match attack signatures against HTTP payloads — SQL injection, XSS, malformed requests. With XProtocol, a tampered payload is cryptographically detectable — the signature won't verify. Schema validation makes injection attacks structurally impossible before application logic is reached. The WAF rule engine collapses to: drop events that fail signature verification. Thousands of pattern-matching rules replaced by one mathematical check.

Firewalls and Security Groups

Firewall rules encode authorization policy as network topology. With XProtocol, authorization is in the event itself. Firewall policy for an XProtocol-native service becomes: accept XProtocol events on the relay port, drop everything else. Inter-service security group rules encoding service-to-service authorization are eliminated. Authorization policy is expressed in the capability model, enforced cryptographically on every event.

VPCs and Network Segmentation

Multi-tier VPC architecture isolates environments by network position. With XProtocol's environment model, environments are a cryptographic concept: a developer's key simply doesn't have capability to touch production data — enforced at the event level, not the network level. One physical infrastructure. Multiple logical environments. The 3–5x infrastructure cost of environment duplication is eliminated. See the XProtocol-Native Environment Model (Strategic Concepts, Concept 2) for the full specification.

Secrets Management

API keys, OAuth client secrets, service account credentials, and webhook signing secrets are eliminated. The secrets management footprint shrinks from hundreds of credential types across dozens of systems to a well-defined key hierarchy, appropriate for hardware security module protection.

Audit Logging and SIEM

Log pipelines exist because services generate logs after the fact, and logs can be tampered with. XProtocol events are the operations themselves — signed at creation, tamper-evident by construction. The Event Store IS the audit trail. No log shipping agents. No centralized aggregation infrastructure. No log tampering risk. Cryptographically stronger guarantees than any log pipeline.

Distributed Tracing

OTel agents, trace collectors, and aggregation infrastructure require separate instrumentation of every service. XProtocol's trace.* annotation namespace in the Graph Store replaces this — every span is signed by the system that produced it, assembled from the event graph, tamper-evident by construction. No collector infrastructure. No separate trace storage.

Multi-Environment Infrastructure

Dev, QA, staging, and production each running full infrastructure copies represents 3–5x the necessary infrastructure spend. With XProtocol's environment model, environment creation is a signed event, not a provisioning operation. Instant ephemeral environments. Deployment promotion is a key authorization event. Config drift between environments is structurally impossible — there is one infrastructure, and the environment is data, not topology.

Full Treatment

For the complete analysis of infrastructure implications including the enterprise cost reduction story, per-category detail, and phased adoption path for infrastructure teams, see XProtocol-Infrastructure-Implications.md.


What XProtocol Does Not Attempt To Solve

A protocol that claims to solve everything solves nothing. XProtocol is ambitious but bounded. These are the things it explicitly does not do:

XProtocol does not eliminate the need for business logic. XProtocol transports events and enforces identity. What a service does with those events — how it processes an order, evaluates a loan application, routes a delivery — is business logic that lives inside the service. XProtocol doesn't generate business logic, optimize it, or replace it.

XProtocol does not guarantee semantic interoperability. Two services can both implement a crm.opportunity.create schema and mean completely different things by "opportunity." XProtocol ensures structural compatibility (the fields match). Semantic compatibility (the concepts match) requires human coordination, community schema standards, and domain expertise. The protocol can't solve this alone.

XProtocol does not guarantee distributed consensus. The saga pattern and optional 2PC provide coordination primitives, not consensus guarantees. True distributed consensus (Byzantine fault tolerance, total ordering across independent services) is a fundamentally harder problem than XProtocol addresses. XProtocol provides tools for coordination; it does not provide distributed consistency guarantees.

XProtocol does not prevent poor schema design. A vendor can publish a schema with 500 required fields, no documentation, inconsistent naming, and breaking changes every week. XProtocol provides the structure for good schemas. It does not enforce good design. Community norms, compatibility certification, and market pressure are the quality enforcement mechanisms — not the protocol.

XProtocol does not remove all centralization pressures. DNS is centralized (ICANN). Seed directories introduce trust anchors. Popular relays will attract more traffic. Large vendors will have more influence over community schemas. XProtocol reduces centralization dramatically compared to the current model, but it does not eliminate the economic and social forces that produce centralization. It provides escape hatches (self-hosted relays, self-hosted discovery, forkable schemas) but cannot prevent consolidation.

XProtocol does not eliminate trust relationships. Cryptographic verification proves that an event came from a specific key. It does not prove the key's owner is honest, competent, or well-intentioned. A signed event from a malicious service is still malicious. Trust in the entity behind the key is a human judgment, aided by reputation systems and community review, not guaranteed by the protocol.

XProtocol does not guarantee AI correctness. An AI agent composing XProtocol events can still make mistakes — query the wrong service, misinterpret the user's intent, compose a valid but incorrect event. XProtocol ensures the event is structurally valid (via GBNF grammars) and properly authenticated. It does not ensure the event is what the user actually wanted. Agent reliability is an AI problem, not a protocol problem.

XProtocol does not replace transport-layer security best practices. End-to-end encryption protects payload confidentiality. TLS protects transport integrity, endpoint authentication, and metadata confidentiality. Both are needed. XProtocol's encryption is defense-in-depth, not a substitute for proper transport security.


Conclusion

The Exchange Protocol is not an incremental improvement to REST, a competitor to GraphQL, or an alternative to Nostr. It is a fundamental rearchitecture of how all digital entities communicate — people with people, people with services, agents with agents, services with services — replacing the fragmented landscape of REST, OAuth, SAML, webhooks, messaging protocols, social APIs, and integration middleware with a unified, identity-native, encryption-default, schema-driven, AI-composable protocol.

The integration tax — the billions of dollars and millions of hours spent connecting incompatible systems — exists because every system speaks a different language and authenticates differently. The communication tax — the dozens of messaging apps, social platforms, and contact management systems — exists because every platform silos identity and data. XProtocol eliminates both. Every system speaks the same language. Every identity is a keypair. Every interaction is a signed, encrypted event.

For the AI era specifically, XProtocol solves the critical gap: how does an AI agent interact with arbitrary people, services, and other agents without custom integration code for each one? The answer is: the AI reads the schema (for services) or composes a structured event (for people), signs it, encrypts it, and sends it. The protocol handles identity, authentication, encryption, and transport. The AI handles intent.

One protocol. One identity. Every exchange.


Appendix — Glossary

Shared definitions used consistently across all XProtocol specifications.

Annotation envelope: The mutable, authorized, unencrypted metadata layer attached to an immutable XProtocol event in the Graph Store. Contains namespaced fields (threading, tracing, inbox state, workflow, AI tags, relationships). Distinct from the signed payload — the event proves what happened; annotations describe how it relates to everything else.

Audio fingerprint: A compact, normalized representation of audio content derived from MFCC, chromagram, and spectral features — used as cryptographic key material via HKDF with fuzzy commitment for environmental tolerance.

Capability: A permission mapping a public key to one or more operations on a service. "This key can read opportunities." Capabilities are stored in the service's permission model and checked on every incoming event.

Commitment (fuzzy): A cryptographic construction allowing a fuzzy match — a recipient's fingerprint F' can recover a sender's committed fingerprint F if their Hamming distance is within tolerance D. Used in visual place recognition and audio fingerprinting to tolerate environmental variation.

Content hash: SHA-256 hash of canonical event fields — used as the event id. Deterministic, unique, tamper-evident.

Correlation ID: A field linking a request event to its response(s). Set by the requester; echoed in the response. Enables request-response semantics over an event-based protocol.

Ed25519: The elliptic-curve signature algorithm used for XProtocol event signing and identity. Fast, compact (64-byte signatures), widely supported.

Event: The atomic unit of XProtocol. Every interaction — a message, a query, a service call, an annotation, a revocation — is an event: signed by the sender's Ed25519 key, encrypted to the recipient's X25519 key, identified by a content hash.

Event Store: An optional extension to a relay that retains events permanently and exposes them via xp.store.* queries. The Event Store is the foundation layer of the Graph Store.

Graph Store: An optional extension to the Event Store that adds a mutable annotation envelope to each stored event — enabling threading, tracing, workflow state, inbox management, typed relationships, and AI semantic tags without modifying the immutable signed event.

Identity Wallet: A secure enclave application (mobile or desktop) that manages a user's XProtocol keypairs, handles social/Shamir recovery, delegates sub-keys, and broadcasts revocations. The user-facing surface of XProtocol's identity model.

Key hierarchy: The tree of Ed25519 keypairs where parent keys sign child keys, establishing chains of authority. Root keys sign organizational keys; organizational keys sign department keys; department keys sign employee/service keys. Any verifier can walk the chain to confirm authority.

Kind: The operation identifier in an XProtocol event — a namespaced string like salesforce.opportunity.create or xp.message.direct. The kind determines which schema the payload must conform to.

Physical context binding: A technique for binding a device's communication private key to its physical installation context (GPS, compass, visual scene, optional UWB) such that the device cannot operate if moved, reoriented, or occluded.

Relay: A server that stores-and-forwards XProtocol events. Mandatory transport for all conformant implementations. The relay sees only ciphertext — it cannot read event payloads. The relay mesh enables decentralized event routing without central coordination.

Reachability profile: A signed event published by each XProtocol participant declaring which discovery transports they support and in what priority order. The basis for transport negotiation.

Schema contract: A machine-readable definition of a service's capabilities — what operations are available, what fields they accept, what permissions are required, and what each operation is for (the semantic field). Supports both Phase 1 (intent-based discovery via xp.schema.describe) and Phase 2 (execution via GBNF grammars). Published by services, consumed by AI agents.

Semantic annotation (semantic field): Structured discovery metadata in a schema contract. Contains intent_verbs, data_subjects, domain, use_when, do_not_use_when, related_schemas, example_inputs, and example_outputs. Advisory — not validated by the store — but critical for reliable agent routing in large schema catalogs. Auto-generated by the MCP Adapter from tool names; enriched by schema authors.

xp.schema.describe: The Phase 1 discovery event. An agent sends an intent description and receives a ranked list of matching schemas with relevance scores and use_when excerpts. Distinct from xp.schema.request, which fetches a specific known schema by name (Phase 2 execution preparation).

Signed event: An XProtocol event whose id (content hash) has been signed with the sender's Ed25519 private key. The signature covers all non-mutable fields. Any verifier with the sender's public key can confirm authenticity and integrity.

Trust tier: A classification of the physical presence assurance level of a discovery transport, from Tier 0 (network only — no physical context) to Tier 5 (full cryptographic physical context binding). Recorded as a signed property of pairing events and enforceable in capability policies.

Visual fingerprint: A compact, normalized representation of a camera image derived from perceptual hashing and structural feature extraction — used as cryptographic key material via HKDF with fuzzy commitment for environmental tolerance.

X25519: The elliptic-curve Diffie-Hellman function used for XProtocol encryption key agreement. A separate X25519 keypair is generated alongside each Ed25519 identity keypair — the two cannot be converted between each other (different scalar derivation functions).

HKDF: HMAC-based Key Derivation Function. Used throughout XProtocol and the Discovery layer to derive symmetric keys from shared secrets, visual fingerprints, audio fingerprints, GPS coordinates, and other inputs.

GBNF: Generalized Backus-Naur Form — a grammar format used to constrain LLM token generation. XProtocol schemas compile to GBNF grammars for AI agent use, making structurally invalid events impossible to generate.

XProtocol.ai is an independent open protocol project and is not affiliated with, endorsed by, or connected to XProtocol.org or any related entities.