# more.md Whitepaper

The agent-readable web: one canonical URL per entity, served as Markdown to machines and a rich page to people, with payment built into the request. A reference design for the Entity Engagement Protocol and the more.md platform that implements it.

_Docs_

The full technical paper, readable here or as a PDF.

[Download](/docs/WHITEPAPER.pdf)

# more.md

*Your entity, as one URL every AI can read.*

*Engineering and strategy companion to the live platform*

**Dr. Ugur Cekmez**

- [https://more.md](https://more.md)
- [https://eep.dev](https://eep.dev)

May 2026

*Version 1.1*

*MIT-licensed release planned*

---

<!-- Mirror of `WHITEPAPER.tex` (same structure and wording). -->

## Abstract

*For humans: see [https://more.md](https://more.md). The rest of this document is the engineering and strategy companion.*

The transition from the human-centric internet to the Agentic Web demands infrastructure that does not yet exist. AI agents cannot efficiently navigate visual layouts, parse non-semantic HTML or discover services through interfaces designed for human eyes. The result is an "HTML Tax" that wastes 80–99% of agent tokens on formatting noise, inflates operational costs and systematically degrades agent accuracy.

**more.md** is a production-grade platform, code complete and pre-public, purpose-built to close this gap. It provides an identity and interaction layer where every entity --- people, organizations, AI agents, products, knowledge bases, places, assets, events and custom types --- is represented as a structured, machine-readable profile accessible via clean Markdown, JSON or Token-Oriented Object Notation (TOON). Built on the **Entity Engagement Protocol (EEP)** [^ref_eep], more.md delivers real-time event streaming, programmable access control, autonomous commerce and cryptographic trust through a single, format-agnostic API surface.

This whitepaper describes the complete more.md platform: its three-tier runtime architecture (Bun/Hono control plane, Go data plane, WebSocket pulse server), its nine entity types with type-scoped URLs, its agent-native features (smart sections, profile changelogs, interaction logs, MCP integration, embeddable badges), live timelines with audience controls (hashtag lanes, authenticated following aggregation), feed-aware search and signed-in notifications, autonomous cryptographic verification (signed `did:web` documents and enveloped Verifiable Credentials, verified in both planes) with numeric trust scoring and anti-fraud defences, its hybrid search engine (full-text + semantic + reciprocal rank fusion), its security posture, its SDK ecosystem (TypeScript, Python, Go CLI) and its operational infrastructure. It also covers the strategic roadmap: live payment rails, registry federation, post-quantum cryptography and decentralized compute markets.

more.md treats the Entity Engagement Protocol as a substrate and composes its value on top. The protocol itself is documented independently [^ref_eep]; this whitepaper focuses on what a working platform built on EEP looks like and how it is engineered. An MIT-licensed release of the platform core, workers and SDKs is planned, with an open-core boundary on the roadmap; the code is currently closed while the platform matures.

*How to read this document:* **Developers** integrating with more.md should focus on Parts II, III, V and X. **Platform operators** deploying or forking the stack should read Parts II, VII and XI. **Investors and strategists** will find the market context in Part I and the roadmap in Part XIII. **Enterprise architects** evaluating adoption should start with Parts VI (EEP), VII (Security) and XII (Compliance). Protocol-level details about EEP itself are in the EEP whitepaper at [https://eep.dev](https://eep.dev); here we describe how more.md consumes and extends that protocol.

**Revision history.**
- **v1.1 (May 2026):** expanded gate requirement-type coverage (13 EEP types, explicit Boolean tree composition with `combine_mode`); documented `/agents.txt` discovery, the `link-cli` agent flow and the Stripe Machine Payment Protocol surface in payment rails; recorded that auto-OR requirement normalisation was removed in May 2026 so publisher intent is preserved verbatim; added `X-EEP-Agent-Capabilities` to the authentication header table.
- **v1.0 (April 2026):** initial public revision.

# Part I: Vision and Context

## The Agentic Shift and the Infrastructure Gap

The global software landscape is undergoing a structural transition. Autonomous AI agents, systems that plan, reason and execute tasks without continuous human supervision, are moving from research prototypes to production deployments. The agentic AI market is projected to grow from USD 7.29 billion in 2025 to USD 139.19 billion by 2034, a compound annual growth rate of 40.50% [^ref_fortune]. Gartner predicts that 40% of enterprise applications will embed task-specific AI agents by the end of 2026, up from less than 5% in 2025 [^ref_gartner].

But the infrastructure these agents must use was never designed for them.

### The HTML Tax

When an AI agent accesses a standard website, it must ingest thousands of lines of HTML, CSS and JavaScript just to extract a single fact. Cloudflare's benchmark of its own blog post showed that raw HTML consumed 16,180 tokens while the Markdown equivalent needed only 3,150 tokens, an 80% reduction [^ref_cloudflare_md]. In extreme cases, content-heavy e-commerce pages can consume hundreds of thousands of tokens before conversion, dropping by up to 99% in Markdown [^ref_cloudflare_agents]. This is the "HTML Tax": a systemic waste of compute, context window and energy that scales with every agent interaction.

The International Energy Agency estimates that a single generative AI query consumes approximately 2.9 Wh of electricity, up to ten times a traditional web search [^ref_iea]. When agents waste most of their tokens parsing visual layouts, this energy cost compounds without producing any additional value.

### The Discovery Vacuum

Beyond format inefficiency, agents face a fundamental discovery problem. There is no canonical registry where an agent can look up "who is this entity, what can it do and how do I interact with it?" Without such a registry, agents fall back on scraping, inference and hallucination. The absence of a standardized identity layer for the Agentic Web is analogous to the pre-DNS internet: technically functional, practically unusable at scale.

### The Access Control Gap

Traditional APIs model access as a binary public/private flag. The agent economy needs a richer model. Real-world resources sit on a spectrum: public, trust-gated, agreement-gated, data-exchange-gated, payment-gated or any combination. Today this is solved by bespoke OAuth flows, per-vendor paywalls, hand-rolled license negotiations and manual compliance emails. Every agent that wants to operate across multiple vendors must rebuild the same logic repeatedly.

### What more.md Solves

more.md closes three gaps simultaneously:

1. **Format efficiency.** Every entity on more.md is served as clean, structured data: Markdown by default, with JSON and TOON available via HTTP content negotiation. No HTML. No scraping. No token waste.
1. **Identity resolution.** Every entity is mapped to a W3C Decentralized Identifier (DID), discoverable through a public API, searchable via full-text, semantic and hybrid search and addressable through a predictable type-scoped URL system.
1. **Real-time awareness and programmable access.** The Entity Engagement Protocol [^ref_eep] provides push-based event streaming (SSE, Webhooks, WebSocket Pulse) and programmable gates (payment, trust, credential, identity, connection, capability, combined) that agents satisfy autonomously.

more.md is the first complete implementation that fuses these three capabilities into a single coherent platform, built end-to-end with SDKs, a CLI, infrastructure scripts and an AI-reviewed runtime.

# Part II: Platform Architecture

## System Architecture

more.md is a multi-service platform split into three application tiers, a shared data layer and asynchronous background workers. All traffic enters through a single Nginx reverse proxy that routes same-origin browser calls (under an `/api/` prefix) and clean-path SDK and agent traffic to the appropriate service based on URL patterns and upgrade headers.

### Architecture Overview

**Figure.** more.md system architecture. Nginx splits traffic between the Bun control plane and the Go data plane, which also serves the `/eep/pulse` and `/ws/messages` WebSocket surfaces. The gateway exposes `/api/`-prefixed paths for the web app and clean paths for agents and OpenAPI. All services share PostgreSQL, Redis and object storage. Background workers consume jobs asynchronously via RabbitMQ.

### Application Layer

#### Go Data Plane

The Go data plane handles read-heavy, latency-sensitive endpoints: profile rendering (Markdown, JSON, TOON), full-text and semantic search, trust score reads with history, DID document serving (`/profiles/{prefix}/{username}/did.json`), dynamic SVG badge generation and Server-Sent Events (SSE) streaming. Content reads under `/{prefix}/{user}/content/...` are served here too, so public agent traffic bypasses the Bun process entirely. The same binary also exposes a WebSocket listener for EEP Pulse (`/eep/pulse`) and for direct-message upgrades (`/api/ws/messages`); Nginx distinguishes paths so the two WebSocket surfaces are routed explicitly.

Gate resolution is implemented natively in this service: matcher, resolver, 402 response builder, per-type proof verifiers and a Redis-cached config loader that is invalidated when the Bun API writes a new configuration. Golden-fixture parity tests between the Go port and the TypeScript reference run on every commit so the two implementations cannot drift (Section [Security Architecture](#security-architecture)).

The dataplane is stateless: it reads from PostgreSQL (via PgBouncer) and Redis and writes nothing to either store. Lock-free atomic counters track active SSE streams and per-service connection caps are declared at startup. Nginx routes `GET /{u,o,l,a,p,k,agent,e,x}/*`, `GET /search*`, `GET /badge/*`, `GET /trust/*`, `GET /stream/*` and the content read paths to this upstream. The gateway health check points at `/api/health` on Bun (which is always up) while `/health/go` probes the dataplane specifically so an operator can tell the two failure modes apart.

#### Bun / Hono API

The primary API server, built on the Bun runtime with the Hono framework, handles everything the data plane does not: authentication, account management, content CRUD, file uploads with preview streaming, document conversion, audio and video ingest, team management, ownership transfers, gate configuration, commerce lifecycle, analytics, admin operations, cron jobs and the native MCP server. It is organized into route modules for account, auth, content, discovery, EEP dispatch, gates, search, profiles, teams, transfers, trust (VC issuance only; the public trust reads live in the Go dataplane), manage, feed, connections, messages, api-keys, admin, analytics, jobs, cron, files, export, changelog, badge, smart-sections, agent-insights, ACP and health.

#### EEP Pulse WebSocket

EEP Network Pulse is implemented on the Go data plane WebSocket listener at `/eep/pulse` (and the gateway-mapped `/api/eep/pulse`). It implements the EEP Network Pulse specification for bidirectional real-time communication. It supports four message types:

- **System:** subscribe, replay, auth refresh, pong.
- **Entity:** publish, update: entity state broadcast.
- **A2A (Agent-to-Agent):** `task_request` → `task_progress` → `task_complete/failed/cancel`.
- **Commerce:** `offer` → `counter` → `accept` → `invoice` → `paid` → `complete` (plus `reject`, `expire`, `dispute`).
- **Chat:** send, history, read: trust-gated direct messaging.

All messages use a versioned `{ v, type, action, seq, data }` envelope. Cross-server delivery uses Redis pub/sub with per-channel monotonic sequence numbers and client-side gap detection with replay. Per-user connection limits (5 free, 20 pro) and token-bucket rate limiting (30 messages/second, configurable) protect against abuse. Close codes follow the EEP specification [^ref_eep]: `4001` for authentication failure, `4003` for nonce/replay violations, `4008` for invalid negotiation transitions, `4010` for connection limit exceeded.

**Direct messaging WebSocket (same listener).**

Direct-message WebSocket upgrades (`/api/ws/messages`) use the same Go dataplane listener; the gateway routes by URL path so Pulse and DM are not conflated. An optional legacy standalone Bun Pulse process is available for custom layouts but is not the default Docker Compose path.

### Data Layer

#### PostgreSQL with Primary/Replica Topology

Core relational data is stored in PostgreSQL 17 with automatic read-replica routing. All queries flow through a `db.execute()` helper which uses `AsyncLocalStorage` to track the HTTP method and write state per request:

- `GET`, `HEAD`, `OPTIONS` with no prior write → replica (read-only).
- `POST`, `PUT`, `DELETE`, `PATCH` → primary.
- `SELECT` after a write in the same request → primary (read-your-own-writes consistency).

In typical workloads, 60–80% of queries hit the replica, reducing primary load. Replication uses PostgreSQL physical streaming replication (WAL) with sub-millisecond lag in healthy deployments.

#### pgvector Semantic Search

The `pgvector` extension stores 1536-dimensional OpenAI `text-embedding-3-small` vectors for both profile bios and content pages. Embeddings are generated asynchronously by the Go embedding worker and indexed for approximate nearest-neighbor search.

#### Redis

Redis serves three roles: (1) event bus via Redis Streams for SSE delivery, (2) pub/sub for WebSocket cross-instance messaging and (3) transient cache for rate limits, brute-force lockouts, trust-score snapshots and session data.

#### Garage S3-Compatible Storage

File uploads (documents, images, converted outputs) are stored in Garage, an S3-compatible distributed object store. Garage replaced MinIO in the production stack for its lower resource footprint and built-in geo-replication. All file operations use the standard S3 API, making the storage layer interchangeable with AWS S3, Cloudflare R2 or any compatible backend.

#### PgBouncer Connection Pooling

Both Go and Bun connect through PgBouncer in transaction pooling mode. This allows thousands of application-side connections to share a small pool of PostgreSQL backends, which is essential when the Go data plane holds tens of thousands of SSE streams simultaneously.

### Background Workers

Heavy asynchronous tasks are processed by isolated workers communicating via RabbitMQ:

**Background workers**

| **Worker** | **Language** | **Queue** | **Purpose** |
| --- | --- | --- | --- |
| `docling-doc-converter` | Python | `doc_convert_queue` | PDF, DOCX, PPTX, XLSX, HTML, LaTeX, EPUB, images (OCR) → Markdown + extracted images |
| `go-embedding-worker` | Go | `embedding_queue` | OpenAI `text-embedding-3-small` vector generation |
| `media-transcribe` | Node/Bun | `media_transcribe_queue` | Groq Whisper (`whisper-large-v3-turbo`) transcription for audio and video uploads; emits timestamped chapters |
| `event-bridge` | Node/Bun | Redis Streams → RabbitMQ | Fan-out from internal event streams to the `eep.events` topic exchange for webhook consumers |

Workers connect to RabbitMQ (or to Redis, for the event bridge), consume jobs and POST results back via signed callback URLs. The document converter supports 14 input formats including OCR for scanned images. The media transcription worker enforces per-tier caps (file size, per-file duration, monthly transcription minutes) at submission time and refunds the minute budget when a job fails so a broken upload does not silently burn the account quota.

### Observability

Logs, metrics and traces flow to an OpenObserve instance via Vector (the log-shipping pipeline from Timber/Datadog). OpenTelemetry instrumentation is wired into both the Bun API and the Go data plane. Planned work extends spans to full EEP lifecycle traces (event emission, Redis `XADD`, Go `XREAD`, SSE push, client acknowledgement) and to webhook delivery pipelines.

# Part III: The Entity System

## Entity Types and Type-Scoped URLs

more.md models the world as a network of **entities**: any person, organization, agent, product, place, asset, knowledge base, event or custom concept that needs a machine-readable presence on the Agentic Web. Every entity has a profile, a DID, composable capabilities and a canonical URL.

### Nine Entity Types

**The nine entity types, their URL prefixes and their composable capabilities**

| X}

**Type** | **Prefix** | **Capabilities** | **Typical Agent Use Case** |
| --- | --- | --- | --- |
| Person | `/u/` | Hireable, Contactable | AI recruiting, professional networking |
| Organization | `/o/` | Authoritative, Serviceable | B2B negotiation, vendor discovery |
| Place | `/l/` | Locatable, Bookable | Logistics, travel, real estate |
| Asset | `/a/` | Monitorable, Operable | IoT management, fleet tracking |
| Product | `/p/` | Purchasable, Shippable | Autonomous procurement, price monitoring |
| Knowledge | `/k/` | Queryable, Referenceable | RAG, research, documentation |
| Agent | `/agent/` | Agent\_Compatible, Streamable | Delegation, sub-agent orchestration |
| Event | `/e/` | Bookable, Attendable | Scheduling, calendar sync |
| Custom | `/x/` | Extensible (JSON Schema) | DAOs, IoT clusters, future entity types |

Usernames are unique *per profile type*, not globally. The entity `/u/ada` (a person) and `/agent/ada` (an AI agent) can coexist under the same handle. Bare `/:username` URLs return an HTTP 409 disambiguation response when multiple profiles share the name, along with a machine-readable list of candidates so the calling agent can pick one programmatically.

### Composable Capabilities

Instead of rigid per-type schemas, entities receive composable capability traits such as `purchasable`, `bookable`, `hireable`, `monitorable` or `streamable`. These traits allow agents to understand which actions are possible without parsing the entire profile. Capabilities are declared in the profile document and extensible via JSON Schema for the custom type.

### Format-Agnostic Delivery

Every entity profile can be served in multiple formats via HTTP content negotiation. The format is selected from the `Accept` header or an explicit `?format=` query parameter.

- **Markdown** (default, `text/markdown`): Optimized for LLM reasoning. Heading levels and bulleted lists provide structural signals that transformer attention mechanisms handle well. Markdown is the most represented structured format in LLM training corpora, giving it a high reasoning-per-token ratio.
- **JSON** (`application/json`): Standard machine-to-machine format. Roughly 1.35–1.50\times more tokens than equivalent Markdown, but convenient for programmatic consumers that already have JSON parsers.
- **TOON** (`text/toon`): Token-Oriented Object Notation [^ref_toon], a compact, indentation-based serialization that encodes the JSON data model losslessly while eliminating curly braces, redundant key names and quotation marks. For uniform arrays, TOON uses a tabular header syntax (e.g., `users{id,name,role}:`) that resembles CSV, drastically reducing repetition. Published benchmarks report TOON consuming on the order of 55% fewer tokens than standard JSON, 25% fewer than minified JSON and 38% fewer than YAML for flat uniform data [^ref_toon_bench].

The critical design principle is **format independence**. TOON is efficient for flat data but less optimal for deeply nested content. Markdown excels at hierarchical reasoning but is less compact for tabular data. Tomorrow, a new format may emerge that outperforms both in specific contexts. Because more.md's entity resolution layer is format-independent, new formats can be integrated without breaking any existing consumer. The platform absorbs the burden of format evolution so neither publishers nor agents need to chase the latest standard.

### W3C Decentralized Identifiers

Every entity on more.md is mapped to a W3C-compliant DID using the `did:web` method. Agents can resolve an entity's DID document via `GET /profiles/{username}/did`, which returns an `application/did+json` response. This provides cryptographic identity binding without requiring blockchain infrastructure. A planned extension adds `did:keri` support for long-lived agent identities that require ambient verifiability and pre-committed key rotation (Section [Strategic Roadmap (KERI)](#strategic-roadmap)).

# Part IV: Agent-Native Features

## Agent-Native Platform Capabilities

more.md is not a website that happens to have an API. It is an agent-native platform where every feature is designed for machine consumption first and human readability second.

### Content Consumption (llms.txt-Style)

Following the emerging `llms.txt` standard [^ref_llmstxt], more.md provides plain Markdown endpoints designed to fit directly into an agent's context window. No authentication is required for public content:

- **Root table of contents** (`GET /content/{username}`): returns a hierarchical Markdown TOC of all categories and pages.
- **Page content** (`GET /content/{username}/{path}`): returns the page content as clean Markdown with metadata headers (`X-Page-Title`, `X-Page-Version`, `X-Category-Path`).
- **Merged content** (`?show=all`): returns all pages under a category merged into a single Markdown document, ideal for feeding entire knowledge sections into an agent's context.

### Smart Sections: Agent-Type-Aware Content

Entities can serve different content to different classes of agent. When an agent identifies itself (via the `X-Agent-Type` header or `?agent_type=` query parameter), the profile response includes only the sections relevant to that agent type. Sections tagged `all` are always included.

This capability addresses real-world scenarios across industries:

- **Healthcare:** a hospital profile serves triage protocols to medical AI agents, insurance billing codes to claims-processing agents and visiting-hours information to patient-scheduling agents, all from the same entity.
- **Real estate:** a property listing shows structural inspection data to due-diligence agents, financing options to mortgage-comparison agents and neighbourhood statistics to relocation-planning agents.
- **Legal:** a law firm's profile provides jurisdictional expertise to legal research agents, fee structures to procurement agents and compliance certifications to regulatory audit agents.
- **Insurance:** an insurance product serves risk assessment parameters to underwriting agents, claims procedures to claims-handling agents and premium comparison data to shopping agents.
- **Education:** a university profile delivers course prerequisites to academic-planning agents, research output to literature-review agents and admission criteria to application-assistance agents.

Smart sections can be managed via a REST API or embedded directly in Markdown using `<!-- agent:type -->` comment syntax, parsed server-side.

### Profile Changelog

Every mutation to a profile, page or category is automatically recorded in an audit trail. The changelog serves three formats optimized for different consumers:

- **Diff format** (default): GitHub-style unified diffs, compact and token-efficient for agent consumption.
- **JSON format**: structured objects with full diff data, actor types and timestamps.
- **TOON format**: ultra-compact for high-frequency monitoring agents.

The changelog tracks the actor type (`human`, `agent` or `system`) for each change, enabling agents to distinguish between human edits and automated updates. A **freshness signal** endpoint (`GET /changelog/{username}/freshness`) provides a quick summary --- last change timestamp, seven-day and thirty-day change counts --- so agents can assess how active and current a profile is without downloading the full changelog.

### Agent Interaction Log

more.md tracks which AI agents access each profile, providing analytics for profile owners. Agents are detected via identity headers (`X-Agent-ID`, `X-Agent-Type`, `X-Agent-Purpose`) and user-agent pattern matching for known agents (OpenAI, Anthropic Claude, Google Gemini, Perplexity, Cohere, GitHub Copilot, LangChain and others). Access is logged asynchronously so that tracking never introduces latency on the request path.

Profile owners see aggregate statistics --- total accesses, unique agents, breakdown by agent type, over time --- through the dashboard API. This creates a feedback loop: entities can optimize their profiles for the agents that actually consume them.

### Embeddable Badges

Dynamic SVG badges (generated by the Go data plane) indicate pipeline-facing status: **ready** (agent-ready), **verified**, **top100**, `pending` or **not found**. That `verified` label reflects automated readiness checks, not the operator workflow in Section [Operator-guided profile verification](#operator-guided-profile-verification). Badges embed like any image URL. They stay cache-friendly, sandboxed (no inline JavaScript) and ship with strict `Content-Security-Policy` headers to prevent SVG-based XSS vectors.

### MCP Server Integration

more.md ships a native Model Context Protocol (MCP) server compatible with Claude Desktop, Cursor, Windsurf, Antigravity, VS Code with GitHub Copilot and any MCP-compatible client. The server exposes eight tools:

1. `search_profiles`: search by keywords, skills or name with type, mode, scope, username and category filtering.
1. `get_profile`: retrieve a profile as JSON or Markdown with agent-type tailoring; `profile_type` disambiguates when a username spans multiple types.
1. `list_profiles`: list profiles by type with pagination.
1. `get_profile_changelog`: change history with freshness signals.
1. `get_agent_insights`: agent access analytics for a profile.
1. `get_trust_score`: read the numeric trust score for a profile, with rolling history.
1. `get_connections`: list a profile's outbound and inbound connections (follows, team membership, ownership).
1. `get_entity_content`: fetch a single page or content category for a profile in JSON, Markdown or TOON.

MCP Resources provide direct URI-based access to profile content: `profile://u/ada`, `profile://o/acme`, etc. The server can be run standalone (`bun run mcp`) or hosted behind the main API; both modes are documented in `docs/MCP.md`.

### Discovery Endpoint

The `GET /discover` endpoint returns a machine-readable map of the entire API surface: supported formats, rate limits, available entity types, gate tiers and protocol capabilities. Before engaging with individual profiles, agents can ingest this manifest to configure their interaction strategy. A parallel endpoint at `/.well-known/eep.json` exposes the EEP-normative subset of this manifest (Section [EEP Integration](#moremd-and-the-entity-engagement-protocol)).

### Link and Agent Discovery

Agents that arrive at a more.md deployment with no prior knowledge of its capabilities discover them through `/agents.txt`, an RFC-style hint file modelled on `robots.txt` and served from the root of every host. The file is a small set of `Key: value` lines: `Agent-Guide:` points at the canonical onboarding Markdown for autonomous clients, `Payment-Protocol:` enumerates the rails the deployment will accept on 402 (`x402, stripe_mpp, stripe_checkout`), `Settle-Endpoint:` lists per-rail settlement URLs and `EEP-Manifest:` resolves back to `/.well-known/eep.json` for the full machine-readable surface. Crawlers can therefore decide in one round-trip whether a target is worth engaging with and which rail their wallet supports.

The companion human-and-agent surface is \href{https://link.com}{`link.com`} and the `@stripe/link-cli` package. An agent that observes `stripe_mpp` in `/agents.txt` or in the rails list of a 402 response installs the CLI on demand (`npx @stripe/link-cli`), authenticates once through the Link mobile or desktop app (a one-time human confirmation that mints a scoped session) and from then on settles gated URLs head-lessly with `mpp pay <gated-url>`. The CLI handles the `WWW-Authenticate: Payment` challenge end-to-end: it parses the second 402 header, obtains a Stripe Payment Token from Link, retries the request with `Authorization: Payment <SPT>` and surfaces the settled receipt to the agent. Operators that want to whitelist this flow configure the Stripe network identifier on the API container; `POST /eep/payment/stripe/mpp/settle` (Section *sec:payment-rails*) uses it to confirm tokens against the publisher's Stripe account.

### File Uploads, Conversion and In-Place Preview

Every profile can accept file uploads through `POST /files` with per-tier limits on file count, total storage, media duration and monthly transcription minutes. Allowed MIME types cover documents, spreadsheets, slides, images, audio and video. When a browser sends `application/octet-stream` (common for unusual extensions), the server resolves the real type from the filename before applying the allow-list, so legitimate formats are not rejected on a technicality.

Two asynchronous pipelines run after the upload lands in Garage:

- **Document conversion.** PDF, DOCX, PPTX, XLSX, HTML, LaTeX, EPUB and image formats (with OCR for scans) are converted to Markdown plus extracted images. The output becomes a normal content page, and the original upload record is linked back to the resulting page.
- **Media transcription.** Audio and video uploads are routed to the `media-transcribe` worker (Groq `whisper-large-v3-turbo` by default). The transcript is stored alongside the file, chapter markers are generated from sentence-segmented timestamps and the derived chapter list is attached to the preview so seek targets are meaningful instead of raw seconds.

Originals are retained after conversion. Earlier versions of the pipeline deleted the source object once Markdown was produced; this meant a user could no longer open the original PDF or PPTX from the UI once conversion finished. The current behaviour keeps the original upload record with the generated page ID attached, so agents and humans can reopen the source artifact without re-uploading. Two endpoints support this:

- `GET /files/{fileId}/content` streams the raw object with `Content-Disposition: inline`, honours the HTTP `Range` header for partial reads (206 responses with `Content-Range`) and forces `attachment` plus a restrictive CSP when the file is SVG. Errors are mapped to 400 (invalid UUID), 401, 403, 404, 416 (range not satisfiable) and 502 (object-store failure) so clients can differentiate transport problems from authorization ones.
- `GET /files/by-page/{pageId}` returns the metadata for the upload that produced a given content page, including `media_kind` and `duration_s`. The query tolerates databases that have not yet applied the `media_kind` migration (PostgreSQL error code `42703`) and retries with a legacy projection rather than 500-ing, so rolling migrations do not take preview down.

The frontend ships a modular preview registry (`components/preview/`) that selects a renderer per MIME type. Video.js handles audio and video with HLS, DASH and native playback and renders a chapter rail over the transport bar. PDFs render in a blob-backed iframe so the browser's built-in viewer is used without needing a PDF worker bundle. Word documents go through `docx-preview`; spreadsheets (`.xlsx`, `.csv`) through SheetJS; images through a plain `<img>`; text, Markdown, JSON and XML through a syntax-aware text renderer. When no renderer matches the MIME, the fallback offers a signed download rather than guessing.

Keeping originals online has two Content-Security-Policy consequences. The `media-src` directive must allow the API origin so Video.js can fetch the streamed file and `worker-src 'self' blob:` must be allowed so PDF and docx renderers can spawn their internal workers. Both are scoped to the API and document origins only.

### Live timeline and feed

Profiles publish short posts to a machine-readable timeline alongside static pages. Create paths live on the Bun API; read-heavy feeds also hit the Go data plane when the gateway forwards matching `GET` routes. Responses follow the usual content negotiation rules (JSON, Markdown, RSS where exposed).

Two knobs control who sees a post. The profile stores a default `live_feed_mode`: `public`, `followers_only` or `per_post`. With `per_post`, the composer chooses each time; otherwise new posts inherit the profile default. Each row carries `visibility` (`public` or `followers_only`). Global listings and RSS stay on `public` material only. Profile timelines merge those flags with follow edges and team roles so followers can read follower-only rows without exposing them on the anonymous home timeline.

`GET /feed/following` returns an authenticated aggregation across accounts the viewer follows. `GET /feed/hashtags/{tag}` exposes a normalized hashtag lane as another discovery surface next to profiles and pages.

Signed-in clients poll notifications under `/notifications`: list and unread counts take a `profile_id` query parameter; `POST /notifications/mark-read` clears state for that profile after team membership checks. Use the same `X-Active-Profile-Id` convention as other multi-profile routes when the UI switches context.

# Part V: Real-Time Event System

## The Event Architecture

Polling REST APIs wastes compute and delivers stale data. more.md implements a push-based event architecture where state changes are broadcast in real time. The system uses a three-stage pipeline: emit → persist → deliver.

### EventBus

When any state change occurs in the Bun/Hono API (profile update, content publish, trust score change, new connection, etc.), the EventBus performs two actions:

1. **Persists** the event to PostgreSQL via batch INSERT (fire-and-forget with retry) for a durable audit trail.
1. **Publishes** the event to Redis Streams via `XADD` for real-time delivery.

Events conform to the CNCF CloudEvents specification [^ref_cloudevents], so downstream consumers can reuse off-the-shelf CloudEvents tooling.

### SSE Signal Stream

The Go data plane delivers signal SSE using an in-process **streamhub**: for each Redis category key (`events:entity`, `events:feed`, ...), one goroutine runs a blocking `XREAD` loop; each message is parsed once and fanned out to subscribers whose filters match. Redis connection use scales with the number of categories, not the number of open SSE clients. History on connect (including `Last-Event-ID` replay) uses the shared application Redis client with `XRANGE` / `XRevRange`, then the client attaches to the hub for live traffic.

- **Global stream** (`GET /stream/signals`): all events across the network, with optional event-type filtering.
- **Per-entity stream** (`GET /stream/{prefix}/{username}/signals?events=...`): filtered to a specific entity with optional event-type selection.
- **Following-scoped stream** (`GET /stream/signals/following`): authenticated; delivers only events whose `profile_id` is the viewer or someone they follow.

**Feed visibility on SSE.**

The public stream (`GET /stream/signals`) drops follower-only feed payloads for anonymous subscribers. Following-scoped sessions carry an authenticated allow-list and receive the full envelope where policy permits. Prefer `/stream/signals/following` when you need follower-only detail instead of relying on the global firehose.

Four strictly typed event schemas form the core data contract:

- `profile.updated`: profile field changes.
- `content.published`: new or updated content pages.
- `trust.score_changed`: trust-score recalculations.
- `connection.followed`: new social connections.

Publishers MAY emit additional namespaced event types (e.g., `com.example.entity.updated`). Agents subscribe with an `events=` filter. Feed-related envelopes honor the follower-only filtering described in the preceding paragraph: follower-only posts never ride the anonymous global stream even though Redis retains the full payload for authorized tails.

The stream sends an SSE comment heartbeat every 15 seconds (`: heartbeat`) so that intermediary proxies (ALBs, Cloudflare) do not drop idle connections. An environment variable sets a soft cap on concurrent signal SSE connections (default very large); Prometheus metrics expose hub subscriber and drop counters.

### Webhooks

For serverless consumers and batch pipelines, more.md delivers events via outbound webhooks. Subscriptions are registered through `POST /eep/subscribe` with a target URL, an event filter and a shared secret. Each delivery carries an `X-EEP-Signature` header containing an HMAC-SHA256 of the canonical request (timestamp + payload) using the shared secret. Delivery uses exponential backoff (1s, 2s, 4s, 8s, 30s, capped at five attempts) and failed deliveries are captured in a dead-letter queue for operator review.

### Redis-to-RabbitMQ Bridge for External Consumers

SSE works for always-connected agents, but serverless functions and corporate networks often need something pull-based. A dedicated `event-bridge` service reads every Redis Streams category using a consumer group (`cg:rabbitmq-bridge`) and republishes each event onto the RabbitMQ topic exchange `eep.events`. External subscribers declare their own queue (with a dead-letter exchange bound to `eep.events.dlx`), register routing patterns converted from EEP wildcards (`**` → `\#`) and consume at their own pace. Entity, content, feed and trust events are marshalled as persistent messages; high-volume analytics and system-metrics events use an explicit per-type TTL so a slow downstream consumer cannot balloon the queue indefinitely.

The **signal SSE hub** uses a small pool of long-lived Redis connections for blocking `XREAD` tails (one reader per category), separate from the short-timeout shared client used for normal cache commands and for `XRANGE` replay. The RabbitMQ bridge remains on **consumer groups** so each bridge replica processes a partition of the stream safely; multiple Go data plane replicas each run their own hub and only serve their local subscribers.

### Guaranteed Delivery

When an agent reconnects after a network interruption, it sends the `Last-Event-ID` header. The Go data plane replays all events after the specified cursor using Redis `XRANGE`, ensuring zero event loss within the retention window. Retention defaults to 72 hours and is configurable per deployment. If a client requests history older than the retained window, the server returns an explicit error so the client snapshots from Layer 1 state instead of assuming an infinite log.

### WebSocket Pulse Delivery

The EEP Pulse WebSocket server subscribes to Redis pub/sub channels per entity for bidirectional delivery. WebSocket messages include monotonically increasing sequence numbers (`seq`) that enable client-side gap detection with automatic `system/replay` requests. Chat messages are persisted to PostgreSQL for history retrieval. JWT re-authentication lets long-lived connections refresh tokens without disconnecting; expired tokens trigger an application-level close code rather than a transport reset.

# Part VI: EEP Integration

## more.md and the Entity Engagement Protocol

The Entity Engagement Protocol (EEP) is a standalone open specification [^ref_eep] for the identity, state and commerce layer of the Agentic Web. more.md is the first production implementation of EEP. This section summarizes how the two fit together without duplicating the full protocol text; readers who want normative specifications, conformance tests or standards-track discussion should consult the EEP repository and whitepaper at [https://eep.dev](https://eep.dev).

### Triple Protocol Stack

EEP defines three layers that more.md implements in full:

- **Layer 1 (State Resolution, REST).** Synchronous profile and content reads with content negotiation (Section [Format-Agnostic Delivery](#format-agnostic-delivery)), exposed by the Go data plane.
- **Layer 2 (Signal Stream, SSE and Webhooks).** Unidirectional push of state change events (Section [The Event Architecture](#the-event-architecture)), exposed by the Go data plane and the Bun API dispatcher.
- **Layer 3 (Network Pulse, WebSocket).** Bidirectional A2A, chat and commerce negotiation on the Go dataplane WebSocket listener at `/eep/pulse`; direct-message WebSocket upgrades (`/api/ws/messages`) share that listener with upstream routing distinguished by URL path in the bundled gateway configurations. An optional standalone Bun Pulse is available for non-default deploys.

### Discovery Manifest

more.md publishes a canonical EEP manifest at `/.well-known/eep.json`:

```json
{
"did": "did:web:more.md",
"eep_versions": ["0.1"],
"preferred_version": "0.1",
"conformance_level": "full",
"layers": {
"l1_state_url": "https://more.md/api/v1",
"l2_subscribe_url": "https://more.md/eep/subscribe",
"l3_pulse_url": "wss://pulse.more.md"
},
"formats": ["text/markdown", "application/json", "text/toon"],
"gate_tiers": ["public", "trust", "credential", "payment"]
}
```

This document is the single source of truth across the platform. Frontend, API and SDKs all derive their discovery state from this one endpoint.

### Canonical EEP Package Suite

more.md consumes the canonical `@eep-dev` npm scope and `eep-dev` PyPI package. The key pieces are:

- `@eep-dev/discovery` --- manifest and registry discovery.
- `@eep-dev/gates` --- gate resolution and proof validation.
- `@eep-dev/signer` --- HMAC-SHA256 webhook signing and verification.
- `@eep-dev/validator` --- SSRF prevention, nonce/replay handling and schema validation.
- `@eep-dev/middleware` --- Hono adapter that wires the above into the request pipeline.
- `@eep-dev/compliance-cli` --- three-tier conformance test runner (Core, Standard, Full) used in CI.

Each release of more.md pins the `@eep-dev` versions it has been verified against and the continuous integration pipeline runs `compliance-cli verify --level full --report-html` against the running stack on every pull request.

### Federation and Registry Interop

more.md can register itself with `eep.dev` (the bootstrapping registry) or with any federated registry holding a valid Registry Federation Credential [^ref_eep]. Conformance Credentials issued by any federation member are cross-verifiable, so an EU-financial registry and a healthcare-specific registry can both trust more.md manifests without manual allowlisting.

# Part VII: Security and Trust

## Security Architecture

Security is the foundational constraint around which more.md is built, not a feature layer added later. Dependency-level CVE advisories are tracked separately and reported in each release's security notes. Each module ships dedicated security test suites covering authentication bypass, input fuzzing, SSRF, DNS rebinding, timing attacks, zip-slip, symlink traversal and injection.

### Authentication

Three authentication methods are supported:

**Authentication methods**

| **Method** | **Mechanism** | **Use Case** |
| --- | --- | --- |
| API Key | `X-API-Key: mmd_...` | Programmatic / machine-to-machine access, scoped read/write |
| Bearer Token | `Authorization: Bearer <jwt>` | Programmatic sessions and clients that supply a JWT out of band; 24-hour default expiry |
| Cookie | `more_session=<token>` | Browser sessions after login; set via `Set-Cookie` (HttpOnly, Secure, SameSite=Lax); login JSON does not echo the JWT |

JWT secrets are mandatory with a minimum 32-character requirement; deployments without a JWT secret refuse to start. Tokens are never returned in response bodies, only via HttpOnly cookies. Per-account brute-force protection locks accounts after ten failed attempts for fifteen minutes; the lockout is tracked in Redis with atomic increment-or-expire semantics to avoid race conditions.

#### Agent-Negotiated Request Headers

Alongside the credential-bearing headers above, the API recognises a small set of agent-supplied headers that shape negotiation rather than authenticate the caller. These are advisory: the server is free to ignore them, but well-behaved deployments use them to keep the 402 and discovery surfaces minimal.

**Agent-negotiated request headers**

| **Header** | **Purpose** |
| --- | --- |
| `X-Agent-ID` | Stable identifier for analytics and the agent interaction log. |
| `X-Agent-Type` | Agent class (`research`, `shopping`, `compliance`, ...) used by smart-section routing. |
| `X-Agent-Purpose` | Free-text intent string surfaced to publishers and audit gates. |
| `X-EEP-Agent-Capabilities` | Comma-separated list of payment rails the agent can drive (e.g. `x402, stripe-mpp`). On 402 the server reorders `accepts[]` so the intersection with the gate's accepted rails appears first; absent the header, the server emits all accepted rails in publisher-declared order. |
| `X-Active-Profile-Id` | Selects the active profile for multi-profile sessions; required for context-sensitive read and write routes. |

### Trust Scoring

more.md computes a `trust_score` for every entity from a weighted set of signals. The verification-backed signals — verified domain control, email, identity/KYC and operator-confirmed authority-to-represent — are *pure database reads* of persisted verification rows, sitting alongside profile completeness, consistency and engagement signals. Moving all network I/O out of the scoring loop and into the verification flow makes scoring fast, deterministic and re-scorable synchronously the moment a verification succeeds; an hourly cron remains a batch safety net, with full history and delta tracking persisted for auditability. Trust scores serve as a native gate type. Negative signals are applied conservatively: an operator-confirmed duplicate-entity or plagiarism flag caps the score (a post-average cap, never a diluting averaged term), so a single confirmed fraud cannot be averaged away. A public-data registry match alone never raises the score.

### Autonomous verification and the verified badge

more.md verifies that a profile genuinely belongs to — or is authorised by — the entity it claims to represent, through six first-class methods persisted per `(profile, method, target)`: `email`; `domain_control` (DNS-TXT, well-known and meta-tag, all SSRF-guarded); `social_proof` (a signed nonce or `rel=me` link-back); `kyc_identity` (Stripe Identity); `org_registry` (GLEIF LEI and EU VIES VAT legal-name match); and `authority_to_represent` (a composite proving the account both controls an official domain and matches a real legal entity).

A data-driven per-type criteria matrix (`verification_requirements`) defines, for each entity type, the required and optional methods plus a declarative `badge_rule`. When the rule is satisfied by cryptographic or registry evidence, the "verified" badge is granted *autonomously* — no human in the loop for the common case — and trust is re-scored synchronously. The operator queue is repositioned as the borderline, appeal and revoke lane: a method that cannot be proven autonomously from free data resolves to a `manual_review` status that an operator confirms. In particular, because public registries expose no authoritative website, `authority_to_represent` never auto-verifies, and a badge is never granted on a public-data name-match alone (an entity's LEI/VAT id is public and proves no control) — so an impersonator who cites a real company's public registration cannot auto-earn a badge.

### W3C Verifiable Credentials 2.0 and the cryptographic trust anchor

Trust and verification facts are issued as machine-verifiable W3C Verifiable Credentials (Data Model 2.0) [^ref_vc], typed `MoreMDEntityCredential` and valid for ninety days by default, with a `credentialStatus` pointing at a real-time revocation endpoint. more.md publishes a *signed* `did:web:more.md` issuer DID document (Ed25519 `verificationMethod`, served at `/.well-known/did.json`) and signs each credential as an **enveloped `vc+jwt`** (compact JWS, EdDSA) — chosen over JSON-LD so the data plane can verify a credential *inline* without RDF canonicalisation. Verification is enforced in *both* planes (Bun control plane and Go data plane): the signature against the issuer key resolved by `kid`, issuer equals `did:web:more.md`, the validity window, **holder binding** (the credential subject must be the presenter — anti-replay, so a leaked credential is not a bearer token) and revocation against the credential revocation registry. Both planes fail closed when verification cannot complete, and a credential without an id — which could never be revoked — is rejected.

**Sybil resistance and anti-fraud.** Verification alone does not stop a determined adversary from minting many entities or copying another's data, so more.md adds defence in depth: a disposable-email blocklist at signup, duplicate-entity detection (SimHash over identity fields) and page-content plagiarism detection (MinHash over *public* page content, cross-owner, attributing the later-published page as the copier). All detection is advisory — it writes `flagged` rows for operator review and never auto-penalises, since legitimate near-duplicates exist (two real "John Smith" profiles, shared boilerplate); only an operator-*confirmed* flag caps trust or withholds a badge.

### Gates: Programmable Access Control

EEP replaces binary public/private access with entity-defined **tiers**, where the owner picks tier names, assigns requirements and lists accessible resources. The default conjunction across a tier's top-level requirement list is AND; `combined` groups (below) lift that restriction by carrying an explicit `combine_mode`. more.md surfaces the thirteen EEP requirement types listed in Table *tab:gates*.

**Gate requirement types supported by more.md**

| **Type** | **Description** |
| --- | --- |
| `payment` | Payment-rail-agnostic. Publishers select x402, Stripe MPP and/or Stripe Checkout rails per gate. Launch receipts are server-issued after x402 V2 facilitator settlement, verified Stripe MPP settlement (Section *sec:payment-rails*) or verified Stripe Checkout settlement. Raw transaction hashes and oracle attestations fail closed until rail-specific cryptographic verification is wired. |
| `trust` | Minimum trust-score threshold. |
| `identity` | DID verification, email confirmation, domain ownership or KYC credential. |
| `credential` | W3C Verifiable Credential from a specified issuer DID. |
| `connection` | Social relationship: follower, mutual or similar graph edge. |
| `capability` | Requesting agent must declare specific capabilities in its DID document. |
| `reciprocal` | Symmetric obligation: the requester must grant the publisher an equivalent access right (mutual-follow, mutual-credential, mutual-data-share). |
| `data_request` | Structured data exchange with explicit purpose, retention and consent fields satisfying GDPR purpose limitation. |
| `agreement` | Acceptance of a named terms document, typically a DID-signed acknowledgement of a specific terms hash. |
| `standard_residency` | Data-residency assertion: the requester's processing locale matches a publisher-declared jurisdiction allow-list. |
| `proof_of_intent` | Declarative statement of the requesting agent's task, used by audit gates and downstream policy engines for after-the-fact attribution. |
| `combined` | A Boolean group; see "Requirement Types and Tree Composition" below. |

Custom requirement types use the `x-` prefix for extensibility. When an agent requests a gated resource without sufficient proof, the API returns HTTP 402 (payment), 403 (non-payment) or 451 (legal) with a machine-readable body specifying which requirements are missing, which tiers are available and how to satisfy them. The agent collects proofs and submits them atomically in a single retry; partial proofs are rejected until the bundle satisfies the combined policy.

#### Requirement Types and Tree Composition

A tier's requirement list is a tree, not a flat conjunction. Each `combined` node carries a `combine_mode` of `all` (logical AND) or `any` (logical OR) and a `children` array of further requirements; children may themselves be `combined` groups, so publishers can express arbitrary Boolean policies such as "(`payment` `OR` `credential`) `AND` (`trust` \geq 50 `OR` `connection.follower`)". The EEP validator enforces a minimum of 2 and a maximum of 10 children per group at any depth; the editor UI mirrors that constraint so authors cannot save trees the protocol would reject.

Auto-OR normalisation was removed from the gate pipeline in May 2026. Earlier releases rewrote sibling requirements of the same type into a synthetic `combined` group with `combine_mode = 'any'` to soften strict-AND semantics; this discarded publisher intent and made tier diffs lossy across versions. The current implementation persists, evaluates and re-serialises every node exactly as authored, so a tier saved as "three payment options under `combine_mode = 'any'`" returns from `GET /gates/...` with that structure intact and a tier saved with three independent top-level payment requirements remains a strict conjunction.

A universal proof framework, currently in development under Wave A of the curried-Turing roadmap, generalises proof submission so that any node in the tree (not only top-level requirements) can be resolved atomically against a single bundle. The runtime gate resolver and the 402-response builder are designed for this evolution; tracking issues and the canonical reference suite live in `@eep-dev/gates`.

**Native enforcement in the Go data plane.** As of the April 2026

release, gate resolution is implemented natively in the Go data plane
(matcher, resolver, HTTP 402
builder, Redis-cached config loader and per-type verifiers). Content routes
(`/u/:username/...`, `/o/:org/...`, ...) resolve the
profile's gate configuration, extract proofs from request headers
(`X-EEP-Proof-<Type>`), call the Go resolver and, on denial, emit a
402 response carrying `WWW-Authenticate: EEP realm="gate", resource="..."`
and `X-EEP-Gates-Config: https://more.md/eep/gates/<did>` so agents
can discover tier metadata without a second round-trip. Golden-fixture
parity tests between the Go port and the TypeScript reference
(`@eep-dev/gates`) run on every commit to prevent divergence.

**Specificity and cache coherence.** Gate resolution applies a *specificity override*: when a non-default tier declares a strictly more specific access pattern for a resource than the default tier's wildcard (for example `content.premium.*` vs. `content.*`), the default tier cannot satisfy the request until proofs match the gated tier---preventing accidental public access to premium paths. Configuration changes made through the Bun API invalidate the Go dataplane's Redis memoization for that profile so enforcement cannot lag writes.

### Replay Protection and HMAC Rotation

All webhook deliveries include a monotonic nonce and a timestamp. The receiving endpoint (and the canonical `@eep-dev/signer`) enforces a 60-second timestamp tolerance and consumes the nonce atomically via Redis `consumeIfFresh`-style primitives, preventing check-then-mark race conditions in distributed deployments. Signing keys support dual-key overlap for rotation: operators can add a new key, wait for subscribers to pick it up and retire the old key without breaking in-flight deliveries.

### CSP and Transport Security

All HTTP responses carry strict `Content-Security-Policy`, `X-Content-Type-Options: nosniff`, `Referrer-Policy: no-referrer-when-downgrade` and `Strict-Transport-Security` headers. SSE and WebSocket upgrade responses additionally restrict `connect-src` and `frame-ancestors` to prevent clickjacking and unauthorized cross-origin connections for browser-based agents. The `media-src` and `worker-src` directives are opened just enough for the in-place file preview (Section [File uploads and preview](#file-uploads-conversion-and-in-place-preview)) to work: `media-src` allows the API origin so Video.js can stream from `/files/{id}/content` and `worker-src 'self' blob:` lets the docx and PDF renderers spawn their internal workers.

### Rate Limiting and Fair Use

Rate limits are split into per-bucket budgets rather than one global counter, so a heavy background sync does not starve interactive traffic. The buckets are `read`, `write`, `auth`, `search`, `manage_read`, `manage_write`, `eep_read` and `eep_write`. Each route declares its bucket explicitly; the middleware refuses to run if a route has no declaration, which is how drift between route files and limit configuration is caught in CI.

Enforcement is Redis-backed using a single Lua script that atomically increments and expires the bucket key, returning the current count and remaining TTL in one round-trip. This prevents the classic `INCR` then `EXPIRE` race where a client can sneak requests past the cap if an expiry lands between the two commands. Keys are scoped by IP, user ID, API key or DID depending on the authenticated principal and the response always includes `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` and `Retry-After` so well-behaved agents can self-throttle.

Browsers get a larger multiplier than headless clients. The middleware inspects `Sec-Fetch-Mode` and `Sec-Fetch-Site`: a `navigate` or `cors` request from a same-origin document is treated as interactive, while a bare API call with no `Sec-Fetch-*` headers is treated as machine traffic. Both paths share the same code; only the multiplier changes. This is the right trade because a logged-in human clicking around a content tree can burst at ten to fifteen requests per second for a few seconds, where an agent usually holds a steadier shape.

A forthcoming sliding-window variant replaces the fixed windows with Redis sorted sets for boundary smoothing (Section [Strategic Roadmap](#strategic-roadmap)); the bucket split and the Lua primitive are already in place.

# Part VIII: Commerce and Marketplace

## Autonomous Commerce

more.md supports autonomous agent-to-agent commerce through three layers: an internal commerce state machine for bilateral negotiation, a service catalog for discovery and bridges to payment rails for settlement.

### Commerce State Machine

The `commerce` message type runs over the Layer 3 WebSocket connection. Services flagged as `negotiable: true` allow two agents to enter the following state machine:

`open` → `countered` → `accepted` → `rejected/expired` → `invoiced` → `paid` → `completed/disputed`

Seven pricing models are supported out of the box: `fixed`, `per-request`, `per-event`, `subscription`, `metered`, `tiered-volume` and `free`. Custom models use the `x-` prefix. Every negotiation produces an invoice/receipt pair with cryptographic payment proofs, creating an audit trail even when the protocol does not process payments directly.

Invalid transitions are rejected at the server; the API tests cover all valid paths, all rejections and dispute lifecycles (dispute from `accepted`, `invoiced` or `paid`; arbitrator evidence collection; resolution; refund or release).

### Service Catalog and Negotiation

Entities publish machine-readable **service catalogs** at `GET /{prefix}/{username}/services` with pricing, availability, delivery methods, tags and a `negotiable` flag. Agents find these catalogs through the same EEP endpoints used for entity resolution; no separate marketplace infrastructure is required. A `POST /{prefix}/{username}/negotiate` endpoint initiates a negotiation session, returning a Pulse WebSocket URL bound to that negotiation.

### Payment Rails

more.md's payment gate is rail-agnostic. The publisher declares in its tier manifest which rails it accepts, the agent declares which it can drive through `X-EEP-Agent-Capabilities` (Section *sec:auth-headers*) and the 402 response is reordered so the intersection appears first in `accepts[]`. Three surfaces are supported, each with rail-specific verification but a shared HS256-signed receipt persisted server-side:

- **x402 V2 [^ref_x402] (agent, on-chain).** The server responds with HTTP 402 and a `PAYMENT-REQUIRED` header specifying accepted token, amount, address and network. The agent constructs a signed x402 V2 payment payload using its wallet and resends the request with `PAYMENT-SIGNATURE`. The Go data plane hands settlement to Bun, Bun calls the allowlisted facilitator's `/verify` and `/settle` endpoints, persists the receipt and returns `PAYMENT-RESPONSE`.
- **Stripe Machine Payment Protocol (MPP) (agent, header-driven).** A second `WWW-Authenticate: Payment id="*challenge*", method="stripe", network="*network_id*", ...` header is appended to the 402 alongside the x402 challenge, so an agent that advertises `stripe-mpp` sees both options in one round-trip. The agent obtains a Stripe Payment Token (SPT) --- typically through `link-cli` (Section *sec:agents-txt*) --- and retries the original request inline with `Authorization: Payment <SPT>`. The API forwards the inline token to `POST /eep/payment/stripe/mpp/settle`, which confirms it against Stripe using the operator-configured Stripe network identifier, persists the settled charge against the gate's challenge nonce and returns the standard receipt. Settling out-of-band against the explicit endpoint is also supported for agents that prefer to split challenge and retry.
- **Stripe Checkout (human / browser agent, virtual-card).** For browser-led flows, the gated page opens a Checkout Session on the publisher's connected account. Session metadata carries the same challenge nonce, resource and profile binding as x402, so Stripe webhooks reconcile `payment_attempts` and a paid session can be exchanged for the same JWS receipt shape. The same Checkout flow accepts virtual PAN credentials issued by `link-cli`, which lets an agent that has not implemented MPP natively still settle through a Link-issued card by typing the PAN into the embedded form --- useful for legacy stacks that need browser-grade compatibility.

AP2 [^ref_ap2] mandates remain on the medium-term roadmap and are accepted today only when carried as W3C Verifiable Credentials; native AP2 settlement, raw transaction hashes and third-party oracle attestations stay deferred until rail-specific cryptographic verification is wired. The full wire format, header conventions and error codes are documented in `docs/eep/x402.md` and `docs/eep/stripe-mpp.md`.

**Wallet linking and in-browser settlement.** When the wallet flow is enabled, sellers prove payout-address ownership with Sign-In with Ethereum (EIP-4361) before an x402 payout option can be enabled; verified wallet rows bind to the profile's x402 payment options. For USDC on Base and Ethereum mainnet, payment-required payloads can include `accepts[].extra.eip3009` so a browser wallet signs EIP-3009 `transferWithAuthorization` typed data and retries the gated URL with `PAYMENT-SIGNATURE`. Operators configure the public hostname, the allowed wallet networks, an optional WalletConnect project id on the frontend and facilitator or in-process RPC policy.

**Launch scope and shared receipt.** A publisher declares a

`payment` requirement in a gate tier and lists accepted rails (`x402`, `stripe_mpp`, `stripe_checkout`); the 402 response carries one entry per accepted rail and is reordered to match the agent's declared capabilities. All three surfaces mint the same HS256-signed receipt, checked by the Go data plane on hot content routes and used to gate the `invoiced → paid` transition. The Go enforcer therefore stays oblivious to the settlement path: it only verifies the receipt signature and binding.

### Reviews and Reputation

After a transaction completes, agents can leave a review (integer score 1–5, optional comment). Reviews are aggregated per service into a rating that other agents use to select providers. The review system was designed for machines from the start: no star graphics, no emotional language, just structured numerical feedback with optional DID-signed attestations. A planned dispute arbitration workflow extends the state machine to support subscriber or provider-initiated disputes with arbitrator assignment, evidence collection and resolution escrow release.

# Part IX: Search and Discovery

## Multi-Modal Search Engine

more.md implements a three-pronged discovery engine that lets agents find entities based on exact keywords, abstract concepts or a combination.

### Keyword Search (Full-Text)

PostgreSQL full-text search with `ts_vector` indexing. Fast exact-match lookups across profile fields (name, bio, skills, affiliations) and content pages. Supports type filtering, pagination and sort-by-recency. Keyword mode also accepts `scope=feed` (and `scope=all`) so queries return matching posts with viewer-aware handling for follower-only rows; those scopes bypass the Redis cache so results stay consistent with live visibility rules.

### Semantic Search

Vector similarity search via `pgvector` with 1536-dimensional OpenAI embeddings. Agents can search by abstract concepts ("machine learning expertise in healthcare") and receive chunk-level results with cosine similarity distances. Scope filters allow searching within profiles only, content only or both.

### Hybrid Search

Combines full-text keyword results with vector similarity using **Reciprocal Rank Fusion (RRF)** [^ref_rrf]. Each result receives a fused score from both ranking systems, ensuring that exact keyword matches and semantically similar results are both represented. If embeddings are unavailable for any reason, hybrid search gracefully falls back to keyword-only.

### Content Negotiation for Results

All search results respect the `Accept` header. An agent requesting `text/toon` receives results in TOON format; `application/json` returns structured JSON; `text/markdown` returns a human-plus-agent-readable list. This lets agents choose the format that best fits their context-window budget.

# Part X: Developer Ecosystem

## SDKs, CLI and Tooling

more.md provides first-class SDKs for TypeScript and Python, a Go CLI and an MCP server, all planned for release under the MIT License.

### TypeScript SDK (npm: `@more-md/sdk`)

The TypeScript/JavaScript SDK is published as `@more-md/sdk` on npm. A minimal integration:

```typescript
import { MoreMD } from '@more-md/sdk';

const client = new MoreMD({
baseUrl: 'https://more.md',
apiKey: 'mmd_your_key',
});

const profile = await client.getProfile('u', 'ada');
const md = await client.getProfile('u', 'ada', 'markdown');
const results = await client.search('machine learning healthcare');

for await (const event of client.streamSignals()) {
console.log(event.type, event.data);
}
```

The SDK covers all nine entity types, content negotiation, trust queries, DID resolution, SSE streaming and WebSocket Pulse interactions. It is browser-safe (fetch-based) and bundles cleanly in Vite, Next.js, Cloudflare Workers and Node.js.

### Python SDK (PyPI: `more-md`)

The Python SDK requires Python \geq 3.9 and is installed via `pip install more-md`. It mirrors the TypeScript SDK feature surface with async and sync entrypoints, relying on `httpx` for HTTP and `websockets` for Pulse interactions. Optional extras install additional EEP protocol modules from the `eep-dev` Python package.

### Go CLI (`more-md`)

A compiled Go binary distributed via GoReleaser (archives, checksums, Docker images and a Homebrew tap). Install with `go install github.com/for-agents/more.md/more-md-cli@latest` or the Homebrew tap. The primary command is `more-md sync`: it scans project documentation, converts supported formats to Markdown and uploads pages to the connected more.md profile; configuration is stored under `.moremd/.config.json`.

### MCP Server

The MCP server is packaged for Claude Desktop, Cursor, Windsurf and any MCP-compatible client. See Part IV for tool descriptions. Operators can enable the server standalone (`bun run mcp`) or expose it through the main API surface.

### Conformance Tooling

The `@eep-dev/compliance-cli` (TypeScript) runs the three-tier EEP conformance suite (Core, Standard, Full) against any endpoint. Publishers use this to verify their EEP compliance before requesting a Conformance Credential. The CLI emits both JSON and self-contained HTML reports (`--report-html`) so that conformance status can be displayed in build artifacts and internal dashboards without additional tooling.

### TOON Utilities

The `@more-md/toon-utils` package provides parsing, serialization and benchmarking utilities for the Token-Oriented Object Notation format. It is published to npm alongside the SDK. The API and frontend runtimes use the `@toon-format/toon` package for wire-format encode and decode of `text/toon` responses; `@more-md/toon-utils` supports shared helpers and benchmarks in this repository.

### Benchmarking Scripts

A monorepo-level `scripts/benchmark-formats.ts` script benchmarks Markdown, JSON and TOON payload sizes and parse costs for a configurable corpus of profiles. This is the tooling used to generate the published efficiency claims and is run on every release candidate.

### Reference demo and funnel analytics

The repository includes an optional reference simulation: a Docker Compose stack for agents, HTTP 402 gates, x402 settlement and replay (Python SDK `pay_and_get_content`), provided as integration context rather than normative protocol text. Gate stages are persisted as funnel events (Redis stream `events:gate_funnel` plus a consumer). Owners query `GET /analytics/gates/{prefix}/{username}/summary`, `/by-resource` and `/audit`; `/audit` supports the same rolling `window` parameter as aggregates when explicit `since`/`until` timestamps are omitted.

# Part XI: Infrastructure and Operations

## Production Infrastructure

The entire more.md stack is containerized via Docker Compose, enabling reproducible local development, CI integration and production deployments. The infrastructure layer includes:

**Infrastructure services**

| **Service** | **Role** |
| --- | --- |
| PostgreSQL (primary) | Writes, read-your-own-writes queries |
| PostgreSQL (replica) | Read-only queries via WAL streaming |
| PgBouncer | Connection pooling for Go and Bun |
| Redis | Streams, pub/sub, cache, rate limiting |
| RabbitMQ | Job dispatch for doc conversion and embedding |
| Garage | S3-compatible distributed object storage |
| OpenObserve | Observability platform for logs, metrics and traces |
| Vector | Log shipping pipeline (Timber/Datadog Vector) |
| Nginx | Reverse proxy with URL-pattern-based routing |

All Docker images use pinned concrete version tags; `:latest` tags are not permitted in the production compose file. Healthchecks are declared for every long-running service. Performance benchmarks run on every test cycle and fail the build if hot-path endpoints exceed a configurable latency budget.

### Deployment Targets

The reference deployment is a single-node Docker Compose stack for developers and staging. The production SaaS is deployed on a managed platform (Fly.io by default; Terraform and Pulumi modules for AWS and GCP are planned as part of the v1.0 infrastructure release):

- `more.md` → frontend (Next.js, standalone build).
- `api.more.md` → API gateway (Nginx → Bun API / Go data plane).
- `pulse.more.md` → Pulse WebSocket server.
- `status.more.md` → uptime and conformance dashboard.

Managed Postgres (with read replica), managed Redis, managed RabbitMQ and object storage are provided by the cloud vendor. Blue/green deployment with automatic rollback is part of the release workflow.

### Implementation Maturity

The codebase includes the Bun/Hono control plane, the Go data plane, the Pulse WebSocket server, three SDKs (TypeScript, Python, Go), the MCP server, the shared services stack and infrastructure scripts. The project sits at **Technology Readiness Level 7**: validated in a relevant environment, with TRL-8 work on the roadmap.

### Coverage and CI

Test coverage is tracked per package and gated in CI with explicit carve-outs (exception handlers that cannot be reached without patching the runtime, for example) documented in each package's test configuration. The Bun API targets \(\geq 84%\) lines and \(\geq 71%\) branches with documented carve-outs; the Go data plane and frontend each carry their own per-package thresholds. The CI matrix covers the Bun API (Vitest + Go data plane tests), the frontend (Vitest + Next.js build), the services stack (Docker Compose config validation + worker tests), both SDKs, the Go CLI and the toon-utils package. A dedicated EEP conformance job boots the stack and runs `compliance-cli verify --level full` against the live endpoint.

# Part XII: Compliance and Regulatory Fit

## Regulatory Alignment

more.md's design is deliberately aligned with current and anticipated regulatory requirements for AI systems, data processing and digital identity.

### GDPR and CCPA (Data Privacy)

Account deletion (`DELETE /auth/account`) triggers a full GDPR Article 17 data purge [^ref_gdpr] across all stores: profiles, S3 files, embeddings, caches, API keys and session data. Purpose declarations in `data_request` gates implement purpose limitation. `retention_days` fields enforce data minimization. The `data.withdrawal` message provides a programmatic right of erasure that does not require a human-readable form or email thread.

### EU AI Act

The EU AI Act (Regulation EU 2024/1689) [^ref_ai_act] introduces mandatory requirements for AI systems operating within the EU. more.md addresses the Act's core mandates at the architectural level:

- **Article 13 (Transparency):** the changelog records every profile mutation with actor type (human, agent or system), cryptographic timestamp and structured diff. This creates a complete machine-auditable transparency trail that satisfies Article 13's requirement to provide clear, complete and comprehensible instructions for use.
- **Article 14 (Human Oversight):** EEP delegation proofs ensure every autonomous action traces back to a human-authorized scope. Gates enforce operational boundaries at runtime: capability gates restrict which API endpoints an agent can access; identity gates require DID-verified credentials before data access. The Operator Privacy Policy Profile lets deployers define maximum autonomy levels per agent class.

### Agentic Tool Sovereignty

A systemic gap in the EU AI Act's static compliance model emerges when agents make autonomous runtime decisions. Consider: an EU-based research agent, fully compliant at deployment, autonomously calls a US news API during execution. This triggers an unplanned cross-border data transfer that no human authorized and no pre-market conformity assessment anticipated [^ref_agentic_sov].

more.md's programmable gates address this **Agentic Tool Sovereignty** problem through geo-fencing gates (restrict external API calls to approved jurisdictions), data-residency gates (enforce that agent outputs remain within specified storage regions), audit gates (log every external tool invocation with DID-signed receipts) and delegation-scope limits (cap the depth and breadth of autonomous actions an agent can take). By transforming opaque agent behavior into auditable, policy-constrained interactions, more.md converts black-box agents into compliant, inspectable systems.

### DORA, eIDAS 2.0 and Financial Compliance

**DORA (Regulation EU 2022/2554) [^ref_dora].** For financial services, mandatory TLS, JWT authentication, DID-based identity, signed payloads, session revocation and per-DID rate limiting satisfy DORA's requirements for secure inter-system communication and operational resilience.

**eIDAS 2.0 (Regulation EU 2024/1183) [^ref_eidas].** W3C Verifiable Credentials, more.md's native credential format, are the technical backbone of eIDAS 2.0 digital identity wallets. An agent holding its owner's eIDAS-compliant identity wallet can use it directly as an EEP gate-requirement credential.

# Part XIII: Roadmap

## Strategic Roadmap

more.md is production-ready today for identity resolution, content delivery, agent-native features, event streaming and gate-based access control. The following capabilities are on the short- to medium-term roadmap.

### Near-term (v1.0 Public Release)

- **Payment operations depth.** Expand the live x402/Stripe payment rails with richer seller dashboards, refund and dispute workflows and facilitator/asset health reporting.
- **Compliance-CLI in CI.** Run `@eep-dev/compliance-cli verify --level full` against the Docker Compose stack in continuous integration to catch specification drift before release.
- **Sliding-window rate limiter.** Replace fixed-window rate limits with Redis sorted sets so that burst traffic at window boundaries is smoothed.
- **Webhook dead-letter queue.** Capture webhook deliveries that exhaust retries, with operator alerting and a re-delivery control surface.
- **Full OpenTelemetry lifecycle traces.** Extend current request-level spans into end-to-end spans covering emit → Redis `XADD` → Go `XREAD` → SSE push → client acknowledgement and emit → dispatcher → webhook POST → delivery confirmation.
- **Prometheus metrics.** Export gate verification latency histograms, SSE and WS gauges, webhook success/failure counters and event-bus throughput for operational dashboards and SLAs.
- **HMAC key rotation with dual-key overlap.** Add a key-rotation endpoint that generates a new signing key, maintains both old and new keys during a configurable overlap period (default 24 hours) and retires the old key automatically.

### Medium-term

- **Redis Streams consumer groups.** Replace broadcast `XREAD` in the Go SSE handler with `XREADGROUP` for durable, at-least-once event processing.
- **DID rotation (EEP SPEC §7.1).** Implement key rotation for entity DIDs: publish new DID document, maintain dual-key overlap period, update all active subscriptions and invalidate the old key after the grace window.
- **EEP-MCP bridge.** Sit in front of any MCP server and automatically generate an EEP manifest from the tool registry, inject zero-trust DID authentication and add x402 payment gating.
- **Registry federation.** Support cross-registry resolution with sector-specific registries (e.g., `eep.eu` for European financial services, `eep-health.org` for healthcare) federating with the core `eep.dev` registry.
- **Dispute arbitration workflow.** Extend the commerce state machine with arbitrator assignment, evidence collection, decision rendering and escrow release/refund actions.

### Long-term

- **Post-quantum cryptography.** NIST finalized its first post-quantum cryptographic standards in August 2024: FIPS 203 (ML-KEM), FIPS 204 (ML-DSA) and FIPS 205 (SLH-DSA) [^ref_pqc]. more.md is designed for hybrid signatures: a classical EdDSA signature alongside an ML-DSA signature on the same payload. The Go ecosystem provides production-ready tooling (Cloudflare's CIRCL [^ref_circl] and `filippo.io/mlkem768` [^ref_mlkem768]) for constant-time ML-KEM and ML-DSA. The planned migration: (1) add ML-DSA as a supported signing algorithm in the EEP manifest; (2) require hybrid signatures for Full-tier conformance; (3) transition to X25519MLKEM768 hybrid TLS for inter-service communication.
- **KERI (Key Event Receipt Infrastructure).** W3C DIDs provide decentralized identity, but high-frequency agent interactions require a robust key rotation mechanism. KERI [^ref_keri] maintains cryptographically chained Key Event Logs and Key Event Receipt Logs; each rotation, delegation or revocation is recorded as an immutable event. The planned `did:keri` method unifies KERI's ambient verifiability with the DID resolution interface.
- **Decentralized compute marketplace.** As compute scarcity intensifies, agents will rent GPU power dynamically. The EEP commerce state machine, combined with the service catalog and auction pricing mode, enables agents to broadcast compute requests, receive bids from GPU clusters (each a sovereign DID) and execute metered smart-contract payments, creating a liquid decentralized compute market.
- **Agent wallet infrastructure.** For full autonomous commerce, agents need wallets they control within operator-defined limits. EEP specifies three binding models: operator-derived (BIP-32 HD wallets for enterprise fleets), hardware-isolated (TEE/HSM for regulated agents) and OS-keychain (Secure Enclave, Android Keystore for consumer agents). Each model supports spending controls, session keys with bounded delegation and multi-chain wallet management.
- **High-volume M2M pilots.** Financial data feeds (real-time market data via EEP SSE), supply-chain logistics (inventory state changes via webhooks) and IoT device negotiation (energy-grid balancing via WebSocket commerce) are the first pilot verticals.

## Conclusion

The Agentic Web is not a future possibility: it is the present reality. Autonomous agents are already deployed in production, but the infrastructure they depend on was designed for a different era. The HTML Tax, the discovery vacuum and the absence of programmable access control are systemic problems that compound with every deployed agent.

more.md solves these problems with working code. Every entity, person, organization, agent, product, knowledge base, place, asset, event and custom type, gets a clean, machine-readable presence served in the format each agent needs. The EEP protocol provides the event streaming, access control and commerce layer that transforms static profiles into living, interactive nodes in an agent network. An MIT-licensed release of the platform core, SDK packages, background workers and the MCP server is planned, with an open-core split on the roadmap. SDKs ship for TypeScript, Python and Go.

The codebase is production-grade: multi-plane architecture, comprehensive test coverage targets, an AI-reviewed runtime, a unified CI matrix and signed releases. The roadmap extends into live payment rails, post-quantum cryptography, KERI-based key management, registry federation and decentralized compute markets. The foundation is built today; public launch follows in 2026.

[https://more.md](https://more.md)  ·  [https://eep.dev](https://eep.dev)  ·  [https://github.com/for-agents/more.md](https://github.com/for-agents/more.md)



## References

[^ref_eep]: Cekmez, U. and the EEP Community. "The Entity Engagement Protocol (EEP) Whitepaper and Specification." [https://eep.dev](https://eep.dev), 2026.

[^ref_fortune]: "Agentic AI Market Size, Share and Forecast Report 2026–2034." Fortune Business Insights, 2026. [https://www.fortunebusinessinsights.com/agentic-ai-market-114233](https://www.fortunebusinessinsights.com/agentic-ai-market-114233)

[^ref_gartner]: "Gartner Predicts 40% of Enterprise Apps Will Feature Task-Specific AI Agents by 2026, Up from Less Than 5% in 2025." Gartner Press Release, August 2025. [https://www.gartner.com/en/newsroom/press-releases/2025-08-26-gartner-predicts-40-percent-of-enterprise-apps-will-feature-task-specific-ai-agents-by-2026](https://www.gartner.com/en/newsroom/press-releases/2025-08-26-gartner-predicts-40-percent-of-enterprise-apps-will-feature-task-specific-ai-agents-by-2026)

[^ref_cloudflare_md]: "Introducing Markdown for Agents." The Cloudflare Blog, February 2026. [https://blog.cloudflare.com/markdown-for-agents/](https://blog.cloudflare.com/markdown-for-agents/)

[^ref_cloudflare_agents]: "Building Agents That Understand the Web." Cloudflare Developers Documentation, 2026. [https://developers.cloudflare.com/agents/](https://developers.cloudflare.com/agents/)

[^ref_iea]: International Energy Agency. "Energy and AI Report," 2025. [https://www.iea.org/reports/energy-and-ai](https://www.iea.org/reports/energy-and-ai)

[^ref_toon]: Schopplich, J. "TOON Format Specification: Token-Oriented Object Notation," 2025. [https://github.com/toon-format/spec](https://github.com/toon-format/spec)

[^ref_toon_bench]: "New Token-Oriented Object Notation (TOON) Hopes to Cut LLM Costs by Reducing Token Consumption." InfoQ, November 2025. [https://www.infoq.com/news/2025/11/toon-reduce-llm-cost-tokens/](https://www.infoq.com/news/2025/11/toon-reduce-llm-cost-tokens/)

[^ref_llmstxt]: "llms.txt: A Standard for Providing LLM-Friendly Content." llmstxt.org, 2025. [https://llmstxt.org/](https://llmstxt.org/)

[^ref_cloudevents]: CNCF. "CloudEvents Specification v1.0.2," 2024. [https://cloudevents.io/](https://cloudevents.io/)

[^ref_vc]: W3C. "Verifiable Credentials Data Model v2.0." W3C Recommendation, May 2025. [https://www.w3.org/TR/vc-data-model-2.0/](https://www.w3.org/TR/vc-data-model-2.0/)

[^ref_x402]: Coinbase. "x402: An Open Payment Protocol for the Internet," 2025. [https://x402.org/](https://x402.org/)

[^ref_ap2]: "Announcing Agent Payments Protocol (AP2)." Google Cloud Blog, 2026. [https://cloud.google.com/blog/products/ai-machine-learning/announcing-agents-to-payments-ap2-protocol](https://cloud.google.com/blog/products/ai-machine-learning/announcing-agents-to-payments-ap2-protocol)

[^ref_rrf]: Cormack, G. V., Clarke, C. L. A. and Büttcher, S. "Reciprocal Rank Fusion Outperforms Condorcet and Individual Rank Learning Methods." Proceedings of SIGIR, pp. 758–759, 2009.

[^ref_gdpr]: Regulation (EU) 2016/679 (General Data Protection Regulation), Article 17: Right to Erasure. [https://gdpr-info.eu/art-17-gdpr/](https://gdpr-info.eu/art-17-gdpr/)

[^ref_ai_act]: Regulation (EU) 2024/1689 (Artificial Intelligence Act). Official Journal of the EU, July 2024. [https://eur-lex.europa.eu/eli/reg/2024/1689/oj](https://eur-lex.europa.eu/eli/reg/2024/1689/oj)

[^ref_agentic_sov]: Hannecke, M. "Agentic Tool Sovereignty: The EU AI Act Problem Nobody Saw Coming." Medium, 2026. [https://medium.com/@michael.hannecke/agentic-tool-sovereignty-the-eu-ai-act-problem-nobody-saw-coming-869325cd8352](https://medium.com/@michael.hannecke/agentic-tool-sovereignty-the-eu-ai-act-problem-nobody-saw-coming-869325cd8352)

[^ref_dora]: Regulation (EU) 2022/2554 (Digital Operational Resilience Act). Official Journal of the EU, December 2022. [https://eur-lex.europa.eu/eli/reg/2022/2554/oj](https://eur-lex.europa.eu/eli/reg/2022/2554/oj)

[^ref_eidas]: Regulation (EU) 2024/1183 amending Regulation (EU) No 910/2014 (eIDAS 2.0). Official Journal of the EU, April 2024. [https://eur-lex.europa.eu/eli/reg/2024/1183/oj](https://eur-lex.europa.eu/eli/reg/2024/1183/oj)

[^ref_pqc]: National Institute of Standards and Technology. "Post-Quantum Cryptography Standards: FIPS 203, FIPS 204, FIPS 205," August 2024. [https://www.nist.gov/news-events/news/2024/08/nist-releases-first-3-finalized-post-quantum-encryption-standards](https://www.nist.gov/news-events/news/2024/08/nist-releases-first-3-finalized-post-quantum-encryption-standards)

[^ref_circl]: "Introducing CIRCL: An Advanced Cryptographic Library." The Cloudflare Blog, 2019. [https://blog.cloudflare.com/introducing-circl/](https://blog.cloudflare.com/introducing-circl/)

[^ref_mlkem768]: Valsorda, F. "Post-quantum Cryptography for the Go Ecosystem: `filippo.io/mlkem768`," 2024. [https://words.filippo.io/mlkem768/](https://words.filippo.io/mlkem768/)

[^ref_keri]: "KERI: Key Event Receipt Infrastructure." Decentralized Identity Foundation, 2024. [https://identity.foundation/keri/kids/kid0000.html](https://identity.foundation/keri/kids/kid0000.html)
