Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ jobs:

- name: Run tests
run: cargo test --all-targets
env:
MACP_MEMORY_ONLY: "1"

build:
name: Build
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ Cargo.lock

# Claude Code
.claude/
CLAUDE.md
/plans/
/tmp/
/temp/
CLAUDE.md

# OS
.DS_Store
Thumbs.db
.macp-data/
8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
[package]
name = "macp-runtime"
version = "0.3.0"
version = "0.4.0"
edition = "2021"

[dependencies]
tokio = { version = "1", features = ["full"] }
tonic = "0.11"
tonic = { version = "0.11", features = ["transport", "tls"] }
prost = "0.12"
prost-types = "0.12"
uuid = { version = "1", features = ["v4"] }
thiserror = "1"
chrono = "0.4"
serde = { version = "1", features = ["derive"] }
Expand All @@ -17,5 +16,8 @@ tokio-stream = "0.1"
futures-core = "0.3"
async-stream = "0.3"

[dev-dependencies]
tempfile = "3"

[build-dependencies]
tonic-build = "0.11"
314 changes: 183 additions & 131 deletions README.md

Large diffs are not rendered by default.

243 changes: 57 additions & 186 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,215 +1,86 @@
# MACP Runtime Documentation
# MACP Runtime documentation

Welcome to the Multi-Agent Coordination Protocol (MACP) Runtime documentation. This guide explains everything about the system in plain language, whether you are an experienced distributed-systems engineer or someone encountering multi-agent coordination for the first time.
This directory documents the runtime implementation profile for `macp-runtime v0.4.0`.

---
The RFC/spec repository is still the normative source for MACP semantics. These runtime docs focus on how this implementation behaves today: startup configuration, security model, persistence profile, mode surface, and local-development examples.

## What Is This Project?
## What is in this runtime profile

The MACP Runtime — also called the **Minimal Coordination Runtime (MCR)** — is a **gRPC server** that helps multiple AI agents or programs coordinate with each other. Think of it as a traffic controller for structured conversations between autonomous agents: it manages who can speak, tracks the state of each conversation, enforces time limits, and determines when a conversation has reached its conclusion.
- unary-first MACP server over gRPC
- five standards-track modes from the main RFC repository
- one experimental `macp.mode.multi_round.v1` mode kept off discovery surfaces
- strict canonical `SessionStart` for standards-track modes
- authenticated sender derivation
- payload limits and rate limiting
- optional file-backed persistence for sessions and accepted-history logs

Version **0.3** of the runtime implements **RFC-0001**, introducing a formal protocol handshake, structured error reporting, a rich Decision Mode lifecycle, session cancellation, message deduplication, participant validation, mode-aware authorization, and a host of new RPCs for runtime introspection.
## Standards-track modes

### Real-World Analogy
- `macp.mode.decision.v1`
- `macp.mode.proposal.v1`
- `macp.mode.task.v1`
- `macp.mode.handoff.v1`
- `macp.mode.quorum.v1`

Imagine you are chairing a formal committee meeting:
## Freeze profile

1. **Someone opens the meeting** — a `SessionStart` message creates a new coordination session.
2. **The chair announces the rules** — the `Initialize` handshake negotiates which protocol version everyone speaks and what capabilities the runtime supports.
3. **Participants discuss and propose** — agents send `Proposal`, `Evaluation`, `Objection`, and `Vote` messages through the Decision Mode, or `Contribute` messages through the Multi-Round Mode.
4. **The committee reaches a decision** — when the mode's convergence criteria are met, the session transitions to **Resolved** and the resolution is recorded.
5. **After the gavel falls, no more motions are accepted** — once a session is resolved or expired, no further messages can be sent to it.
6. **The chair can also adjourn early** — a `CancelSession` call terminates the session before natural resolution.
The current runtime is intended to be the freeze candidate for unary SDKs and reference examples.

The MACP Runtime manages this entire lifecycle automatically and enforces the rules at every step.
Implemented and supported:

---
- `Initialize`
- `Send`
- `GetSession`
- `CancelSession`
- `GetManifest`
- `ListModes`
- `ListRoots`

## What Problem Does It Solve?
Not part of the freeze surface:

When multiple AI agents or programs need to work together, they need a way to:
- `StreamSession` is intentionally disabled in this profile
- `WatchModeRegistry` is unimplemented
- `WatchRoots` is unimplemented

- **Negotiate a common protocol** — agree on version, capabilities, and supported modes before any real work begins.
- **Start a conversation** — create a session with a declared intent, participant list, and time-to-live.
- **Exchange messages safely** — with deduplication, participant validation, and ordered logging.
- **Track the state** of the conversation — know whether it is open, resolved, or expired at any moment.
- **Reach a decision** — through a structured lifecycle (proposals, evaluations, votes, commitments) or through iterative convergence.
- **Know when it is done** — terminal states are enforced; resolved or expired sessions reject further messages.
- **Cancel gracefully** — terminate sessions explicitly with a recorded reason.
- **Discover capabilities** — query which modes are available, inspect manifests, and watch for registry changes.
## Security model

Without a coordination runtime, each agent would need to implement all of this logic independently, leading to subtle bugs, inconsistent state machines, and fragile integrations. The MACP Runtime centralizes these concerns so that agents can focus on their domain logic.
Production expectations:

---
- TLS transport
- bearer-token authentication
- runtime-derived `Envelope.sender`
- per-request authorization
- payload size limits
- rate limiting

## Key Concepts
Local development shortcut:

### Protocol Version

The current protocol version is **`1.0`**. Every `Envelope` must carry `macp_version: "1.0"` or the message will be rejected with `UNSUPPORTED_PROTOCOL_VERSION`. Before sending any session messages, clients should call the `Initialize` RPC to negotiate the protocol version and discover runtime capabilities.

### Sessions

A **session** is a bounded coordination context — like a conversation thread with rules. Each session has:

- A unique **session ID** chosen by the creator.
- A **mode** that defines the coordination logic (e.g., `macp.mode.decision.v1` or `macp.mode.multi_round.v1`).
- A current **state**: `Open`, `Resolved`, or `Expired`.
- A **time-to-live (TTL)** — how long the session remains open before automatic expiry (default 60 seconds, max 24 hours).
- An optional **participant list** — if provided, only listed senders may contribute.
- An optional **resolution** — the final outcome, recorded when the mode resolves the session.
- **Version metadata** — intent, mode_version, configuration_version, and policy_version carried from the `SessionStartPayload`.

### Messages (Envelopes)

Every message is wrapped in an **Envelope** — a structured protobuf container that carries:

- **macp_version** — protocol version (`"1.0"`).
- **mode** — which coordination mode handles this message.
- **message_type** — the semantic type (`SessionStart`, `Message`, `Proposal`, `Vote`, `Contribute`, `Signal`, etc.).
- **message_id** — a unique identifier for deduplication and tracing.
- **session_id** — which session this belongs to (may be empty for `Signal` messages).
- **sender** — who is sending the message.
- **timestamp_unix_ms** — informational timestamp.
- **payload** — the actual content (protobuf-encoded or JSON, depending on the mode and message type).

### Acknowledgments (Ack)

Every `Send` call returns an **Ack** — a structured response that tells you:

- **ok** — `true` if accepted, `false` if rejected.
- **duplicate** — `true` if this was an idempotent replay of a previously accepted message.
- **message_id** and **session_id** — echoed back for correlation.
- **accepted_at_unix_ms** — server-side acceptance timestamp.
- **session_state** — the session's state after processing (OPEN, RESOLVED, EXPIRED).
- **error** — a structured `MACPError` with an RFC error code, human-readable message, and optional details.

### Session States

Sessions follow a strict state machine with three states:

| State | Can receive messages? | Transitions to |
|-------|----------------------|----------------|
| **Open** | Yes | Resolved, Expired |
| **Resolved** | No (terminal) | — |
| **Expired** | No (terminal) | — |

- **Open** — the session is active and accepting messages. This is the initial state after `SessionStart`.
- **Resolved** — a mode returned a `Resolve` or `PersistAndResolve` response, recording the final outcome. No further messages are accepted.
- **Expired** — the session's TTL elapsed (detected lazily on the next message), or the session was explicitly cancelled via `CancelSession`. No further messages are accepted.

### Modes

**Modes** are pluggable coordination strategies. The runtime provides the "physics" — session invariants, logging, TTL enforcement, routing — while modes provide the "coordination logic" — when to resolve, what state to track, and what convergence criteria to apply.

Five standard modes are built in, plus one experimental mode:

| Mode Name | Aliases | Participant Model | Determinism | Description |
|-----------|---------|-------------------|-------------|-------------|
| `macp.mode.decision.v1` | `decision` | Declared | Semantic-deterministic | RFC-compliant decision lifecycle: Proposal → Evaluation → Objection → Vote → Commitment |
| `macp.mode.proposal.v1` | — | Peer | Semantic-deterministic | Lightweight propose/accept/reject lifecycle for peer-to-peer coordination |
| `macp.mode.task.v1` | — | Orchestrated | Structural-only | Task assignment and completion tracking with orchestrator-driven workflow |
| `macp.mode.handoff.v1` | — | Delegated | Context-frozen | Context transfer between agents with frozen context semantics |
| `macp.mode.quorum.v1` | — | Quorum | Semantic-deterministic | Threshold-based voting where resolution requires a configurable quorum |
| `macp.mode.multi_round.v1` | `multi_round` | Participant-based | Convergence | Participant-based convergence using `all_equal` strategy (experimental, not on discovery surfaces) |

An empty `mode` field defaults to `macp.mode.decision.v1` for backward compatibility.

### Signals

**Signal** messages are ambient, session-less messages. They can be sent with an empty `session_id` and do not create or modify any session. They are useful for out-of-band coordination hints, heartbeats, or cross-session correlation.

---

## How It Works (High Level)

```
Client MACP Runtime
| |
|--- Initialize(["1.0"]) ------------>|
|<-- InitializeResponse(v=1.0) -------| (handshake complete)
| |
|--- Send(SessionStart, s1) --------->|
|<-- Ack(ok=true, state=OPEN) --------| (session created)
| |
|--- Send(Proposal, s1) ------------->|
|<-- Ack(ok=true, state=OPEN) --------| (proposal recorded)
| |
|--- Send(Vote, s1) ----------------->|
|<-- Ack(ok=true, state=OPEN) --------| (vote recorded)
| |
|--- Send(Commitment, s1) ----------->|
|<-- Ack(ok=true, state=RESOLVED) ----| (session resolved)
| |
|--- Send(Message, s1) -------------->|
|<-- Ack(ok=false, SESSION_NOT_OPEN) -| (rejected: terminal)
| |
|--- GetSession(s1) ----------------->|
|<-- SessionMetadata(RESOLVED) -------| (query state)
```bash
export MACP_ALLOW_INSECURE=1
export MACP_ALLOW_DEV_SENDER_HEADER=1
cargo run
```

---

## What Is Built With

- **gRPC over HTTP/2** — high-performance, type-safe RPC framework with streaming support.
- **Protocol Buffers (protobuf)** — binary serialization for efficient, schema-enforced message exchange.
- **Rust** — memory-safe, concurrent systems language with zero-cost abstractions.
- **Tonic** — Rust's async gRPC framework built on Tokio.
- **Buf** — protobuf linting and breaking-change detection.

You do not need to know Rust to understand the protocol or use the runtime — any language with a gRPC client can connect.

---

## Components

This runtime consists of:
In dev mode, example clients attach `x-macp-agent-id` metadata and may use plaintext transport.

1. **Runtime Server** (`macp-runtime`) — the main coordination server managing sessions, modes, and protocol enforcement.
2. **Basic Client** (`client`) — a demo client exercising the happy path: Initialize, ListModes, SessionStart, Message, Resolve, GetSession.
3. **Fuzz Client** (`fuzz_client`) — a comprehensive test client exercising every error path, every new RPC, participant validation, signal messages, cancellation, and multi-round convergence.
4. **Multi-Round Client** (`multi_round_client`) — a focused demo of multi-round convergence with two participants reaching agreement.
5. **Proposal Client** (`proposal_client`) — a demo of the Proposal mode's peer-based propose/accept/reject workflow.
6. **Task Client** (`task_client`) — a demo of the Task mode's orchestrated assignment and completion tracking.
7. **Handoff Client** (`handoff_client`) — a demo of the Handoff mode's delegated context transfer between agents.
8. **Quorum Client** (`quorum_client`) — a demo of the Quorum mode's threshold-based voting and resolution.
## Persistence model

---
By default the runtime persists snapshots under `.macp-data/`:

## Documentation Structure
- `sessions.json`
- `logs.json`

| Document | What It Covers |
|----------|---------------|
| **[protocol.md](./protocol.md)** | Full MACP v1.0 protocol specification — message types, validation rules, error codes, mode specifications |
| **[architecture.md](./architecture.md)** | Internal architecture — component design, data flow, concurrency model, design principles |
| **[examples.md](./examples.md)** | Step-by-step usage examples — client walkthroughs, common patterns, FAQ |
If a snapshot file contains corrupt or incompatible JSON, the runtime logs a warning to stderr and starts with empty state.

---
Disable persistence with:

## Quick Start

**Terminal 1** — Start the server:
```bash
cargo run
```

You should see:
```
macp-runtime v0.3.0 (RFC-0001) listening on 127.0.0.1:50051
```

**Terminal 2** — Run a test client:
```bash
cargo run --bin client
export MACP_MEMORY_ONLY=1
```

You will see the client negotiate the protocol version, discover modes, create a session, send messages, resolve the session, and verify the final state.

---

## Next Steps
## Document map

1. Read **[protocol.md](./protocol.md)** to understand the full MACP v1.0 protocol specification.
2. Read **[architecture.md](./architecture.md)** to understand how the runtime is built internally.
3. Read **[examples.md](./examples.md)** for practical, step-by-step usage examples.
- `../README.md` — root-level quick start and configuration reference
- `examples.md` — updated local-development examples and canonical message patterns
- `protocol.md` — implementation notes and protocol surface summary
- `architecture.md` — runtime component layout
Loading
Loading