|
| 1 | +// SPDX-License-Identifier: PMPL-1.0-or-later |
| 2 | +// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk> |
| 3 | += Agent-MCP Cartridge — Technical Report |
| 4 | +Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> |
| 5 | +:toc: left |
| 6 | +:toclevels: 3 |
| 7 | +:icons: font |
| 8 | +:source-highlighter: rouge |
| 9 | + |
| 10 | +== Executive Summary |
| 11 | + |
| 12 | +Agent-MCP is a formally verified agentic orchestration cartridge for the BoJ (Bundle of Joy) server. It enforces Boyd's OODA loop (Observe → Orient → Decide → Act) as a dependent-type state machine, making it *impossible* for an AI agent to act without first observing, orienting, and deciding. This prevents the "shoot first, think later" anti-pattern that plagues autonomous AI systems. |
| 13 | + |
| 14 | +The cartridge is accessible via *9 protocol transports*: REST, gRPC, GraphQL, WebSocket, JSON-RPC 2.0, MQTT, tRPC, SOAP, and Cap'n Proto — supporting everything from web dashboards to multi-agent swarms. |
| 15 | + |
| 16 | +== Architecture |
| 17 | + |
| 18 | +=== The ABI-FFI-Adapter Triple |
| 19 | + |
| 20 | +[source] |
| 21 | +---- |
| 22 | + Idris2 ABI (SafeOODA.idr, Protocol.idr) |
| 23 | + │ ValidOODA proof: impossible to skip stages |
| 24 | + │ Dependent types enforce state machine correctness |
| 25 | + ▼ |
| 26 | + Zig FFI (agent_ffi.zig) |
| 27 | + │ 32 concurrent sessions, mutex-protected |
| 28 | + │ 30+ tests, C-ABI exports |
| 29 | + ▼ |
| 30 | + V-lang Adapters (9 protocol servers) |
| 31 | + │ REST, gRPC, GraphQL, WebSocket, JSON-RPC, |
| 32 | + │ MQTT, tRPC, SOAP, Cap'n Proto |
| 33 | + ▼ |
| 34 | + AI Agents (Claude, Gemini, custom agents, bot fleets) |
| 35 | +---- |
| 36 | + |
| 37 | +=== Why This Architecture Matters |
| 38 | + |
| 39 | +* The *Idris2 layer* makes invalid state transitions a compile-time error. There is no `ValidOODA Observe Act` constructor — the type system physically prevents it. |
| 40 | +* The *Zig layer* manages 32 concurrent agent sessions with mutex-protected state, ensuring thread safety under load. |
| 41 | +* The *V-lang layer* exposes session management through every protocol pattern, from request/response to pub/sub to binary RPC. |
| 42 | + |
| 43 | +== Core Logic |
| 44 | + |
| 45 | +=== The OODA State Machine |
| 46 | + |
| 47 | +Every AI agent session follows a strict cycle: |
| 48 | + |
| 49 | +[source] |
| 50 | +---- |
| 51 | + ┌──────────┐ |
| 52 | + │ OBSERVE │ ◄─── Gather data, read context |
| 53 | + └────┬─────┘ |
| 54 | + │ (only valid transition) |
| 55 | + ┌────▼─────┐ |
| 56 | + │ ORIENT │ ◄─── Analyse, interpret, contextualise |
| 57 | + └────┬─────┘ |
| 58 | + │ (only valid transition) |
| 59 | + ┌────▼─────┐ |
| 60 | + │ DECIDE │ ◄─── Choose action, plan execution |
| 61 | + └────┬─────┘ |
| 62 | + │ (only valid transition) |
| 63 | + ┌────▼─────┐ |
| 64 | + │ ACT │ ◄─── Execute the decision |
| 65 | + └────┬─────┘ |
| 66 | + │ (loops back) |
| 67 | + └──────────► OBSERVE (new loop, loopCount++) |
| 68 | +
|
| 69 | + Any state ──► HALTED (emergency stop) |
| 70 | + HALTED ──► OBSERVE (resume) |
| 71 | +---- |
| 72 | + |
| 73 | +=== Valid Transitions (Idris2 Proof) |
| 74 | + |
| 75 | +[cols="1,1,1", options="header"] |
| 76 | +|=== |
| 77 | +| From | To | Allowed? |
| 78 | + |
| 79 | +| Observe | Orient | *Yes* — must analyse before deciding |
| 80 | +| Observe | Decide | *No* — cannot skip analysis |
| 81 | +| Observe | Act | *No* — cannot skip analysis AND decision |
| 82 | +| Orient | Decide | *Yes* — must decide before acting |
| 83 | +| Orient | Act | *No* — cannot skip decision |
| 84 | +| Decide | Act | *Yes* — execute the decision |
| 85 | +| Act | Observe | *Yes* — new loop begins |
| 86 | +| Any | Halted | *Yes* — emergency stop always available |
| 87 | +| Halted | Observe | *Yes* — resume with fresh observation |
| 88 | +|=== |
| 89 | + |
| 90 | +The `ValidOODA` dependent type in Idris2 has exactly 9 constructors — one for each valid transition. Any other transition is a *type error at compile time*. |
| 91 | + |
| 92 | +=== Tool Call Safety |
| 93 | + |
| 94 | +Not all agent actions are equal. Agent-MCP classifies tool calls by risk: |
| 95 | + |
| 96 | +[cols="1,1,1", options="header"] |
| 97 | +|=== |
| 98 | +| Tool Call Type | Has Side Effects? | Requires Safety Check? |
| 99 | + |
| 100 | +| Execute | Yes | *Yes* |
| 101 | +| Query | No | No |
| 102 | +| Transform | No | No |
| 103 | +| Communicate | Yes | No |
| 104 | +| Delegate | Yes | *Yes* |
| 105 | +| Escalate | Yes | *Yes* |
| 106 | +|=== |
| 107 | + |
| 108 | +=== Safety Gate |
| 109 | + |
| 110 | +Before execution, a safety check determines whether to proceed: |
| 111 | + |
| 112 | +[cols="1,1,1", options="header"] |
| 113 | +|=== |
| 114 | +| Safety Outcome | Allows Execution? | Needs Human? |
| 115 | + |
| 116 | +| Approved | *Yes* | No |
| 117 | +| Denied | No | No |
| 118 | +| Escalated | No | *Yes* |
| 119 | +| Timeout | No | No |
| 120 | +| Sandboxed | *Yes* (isolated) | No |
| 121 | +| Human Required | No | *Yes* |
| 122 | +|=== |
| 123 | + |
| 124 | +=== Multi-Agent Coordination |
| 125 | + |
| 126 | +[cols="1,1", options="header"] |
| 127 | +|=== |
| 128 | +| Strategy | Description |
| 129 | + |
| 130 | +| Solo | Single agent, no coordination |
| 131 | +| Collaborative | Agents share information and goals |
| 132 | +| Competitive | Agents compete for best solution |
| 133 | +| Hierarchical | Manager agent delegates to workers |
| 134 | +| Swarm | Emergent behaviour from simple rules |
| 135 | +| Consensus | Agents vote before acting |
| 136 | +|=== |
| 137 | + |
| 138 | +=== Agent Memory Types |
| 139 | + |
| 140 | +[cols="1,1,1", options="header"] |
| 141 | +|=== |
| 142 | +| Memory Type | Persistent? | Scope |
| 143 | + |
| 144 | +| Working | No | Current session only |
| 145 | +| Episodic | Yes | Event history |
| 146 | +| Semantic | Yes | Knowledge base |
| 147 | +| Procedural | Yes | Skills and procedures |
| 148 | +| Shared | Yes | Across all agents |
| 149 | +|=== |
| 150 | + |
| 151 | +== Protocol Transports |
| 152 | + |
| 153 | +=== 9 Protocols Available |
| 154 | + |
| 155 | +[cols="1,1,2", options="header"] |
| 156 | +|=== |
| 157 | +| Protocol | Adapter File | Best For |
| 158 | + |
| 159 | +| *REST* | `agent_adapter.v` | Standard web APIs, Claude MCP bridge |
| 160 | +| *gRPC* | `agent_grpc.v` | Microservice agent orchestration |
| 161 | +| *GraphQL* | `agent_graphql.v` | Agent dashboards, flexible session queries |
| 162 | +| *WebSocket* | `agent_websocket.v` | Real-time OODA state streaming, live monitoring |
| 163 | +| *JSON-RPC 2.0* | `agent_jsonrpc.v` | MCP native protocol, batch operations |
| 164 | +| *MQTT* | `agent_mqtt.v` | Distributed agent swarms, edge agents |
| 165 | +| *tRPC* | `agent_trpc.v` | Type-safe frontend agent controls |
| 166 | +| *SOAP* | `agent_soap.v` | Enterprise workflow integration |
| 167 | +| *Cap'n Proto* | `agent_capnproto.v` | High-performance multi-agent coordination |
| 168 | +|=== |
| 169 | + |
| 170 | +=== Protocol Selection Guide |
| 171 | + |
| 172 | +* *Building an agent dashboard?* → GraphQL or WebSocket |
| 173 | +* *Orchestrating a bot fleet?* → gRPC or MQTT |
| 174 | +* *Connecting from an MCP client?* → JSON-RPC (native MCP protocol) |
| 175 | +* *Running agents on edge devices?* → MQTT |
| 176 | +* *Enterprise workflow integration?* → SOAP |
| 177 | +* *Maximum throughput agent swarm?* → Cap'n Proto or gRPC |
| 178 | +* *Simple single-agent integration?* → REST |
| 179 | + |
| 180 | +== Specific Agentic Server Types |
| 181 | + |
| 182 | +=== 1. OODA Compliance Gateway |
| 183 | + |
| 184 | +The most common deployment: every AI agent in an organisation must register a session with Agent-MCP before it can act. The gateway enforces that no agent skips the Observe → Orient → Decide sequence. |
| 185 | + |
| 186 | +*Example flow*: Claude Code starts a task → creates OODA session → Observes (reads code) → Orients (analyses patterns) → Decides (plans changes) → Acts (writes code) → loops back to Observe. |
| 187 | + |
| 188 | +=== 2. Multi-Agent Swarm Controller |
| 189 | + |
| 190 | +Uses MQTT to coordinate dozens of agents working on the same problem. Each agent has its own OODA session; the controller uses the `Consensus` coordination strategy to aggregate decisions before any agent acts. |
| 191 | + |
| 192 | +*Example*: 6 bots in the gitbot-fleet (Rhodibot, Echidnabot, Sustainabot, Panicbot, Glambot, Seambot) each run independent OODA loops, but coordinate via Agent-MCP before making changes to shared repositories. |
| 193 | + |
| 194 | +=== 3. Safety-Critical Agent Sandbox |
| 195 | + |
| 196 | +For high-risk agent actions (code deployment, database migrations, financial transactions), Agent-MCP gates every `Execute` tool call through the safety check. Only `Approved` or `Sandboxed` outcomes allow execution. |
| 197 | + |
| 198 | +*Example*: AI-assisted database migration — agent Observes schema, Orients by checking foreign keys, Decides on migration plan, but Act is blocked until safety check returns `Approved` (human reviews the plan). |
| 199 | + |
| 200 | +=== 4. Hierarchical Agent Orchestrator |
| 201 | + |
| 202 | +Uses gRPC for high-throughput manager → worker delegation. The manager agent runs its own OODA loop, and in the `Act` phase, delegates sub-tasks to worker agents, each with their own enforced OODA sessions. |
| 203 | + |
| 204 | +*Example*: Project manager agent decomposes a feature request → delegates sub-tasks to coding agent, testing agent, documentation agent → each worker follows its own OODA cycle → results flow back to manager's next Observe phase. |
| 205 | + |
| 206 | +=== 5. Agent Audit Trail |
| 207 | + |
| 208 | +Every OODA transition is a logged event. Using WebSocket streaming, a compliance dashboard shows real-time agent activity: which agents are in which OODA phase, how many loops they've completed, whether any have been halted. |
| 209 | + |
| 210 | +*Example*: Regulatory compliance — financial institution must prove that every AI decision followed a structured process. Agent-MCP's OODA log provides a formal audit trail with cryptographic attestation. |
| 211 | + |
| 212 | +=== 6. Adaptive Agent Learning |
| 213 | + |
| 214 | +Uses the `Episodic` and `Procedural` memory types to build agent skills over time. After each OODA loop, the agent stores what worked (episodic memory) and extracts reusable procedures (procedural memory). |
| 215 | + |
| 216 | +*Example*: DevOps agent learns from incident response — each incident is an OODA loop, the agent builds procedural memory of "when X alert fires, check Y then Z", getting faster with each iteration. |
| 217 | + |
| 218 | +== Value Beyond Current Implementation |
| 219 | + |
| 220 | +=== What We Have Now |
| 221 | + |
| 222 | +* Dependent-type proof that OODA stages cannot be skipped |
| 223 | +* 32 concurrent agent sessions with thread-safe management |
| 224 | +* 9 protocol transports for universal accessibility |
| 225 | +* Tool call classification with safety gates |
| 226 | +* Multi-agent coordination strategies |
| 227 | +* Cognitive memory type system |
| 228 | + |
| 229 | +=== What This Enables That Nothing Else Does |
| 230 | + |
| 231 | +1. *Provably Safe Agents*: No other agent framework mathematically guarantees that agents follow a structured decision loop. Agent-MCP's `ValidOODA` proof type makes "act without thinking" a *type error*, not a runtime bug. |
| 232 | + |
| 233 | +2. *Universal Agent Protocol*: The same OODA enforcement works over MQTT (for a Raspberry Pi agent), WebSocket (for a browser-based agent), gRPC (for a Kubernetes agent), and SOAP (for a bank's agent system) — all with the same formal guarantees. |
| 234 | + |
| 235 | +3. *Safety as Architecture*: Tool call classification and safety gates are not config — they are type-level properties. The system knows that `Execute` has side effects and `Query` doesn't, and enforces safety checks accordingly. |
| 236 | + |
| 237 | +4. *Coordination Without Chaos*: The 6 coordination strategies are not just labels — they prescribe how agents interact. `Consensus` means agents vote before acting; `Hierarchical` means only the manager can delegate. The protocol enforces this. |
| 238 | + |
| 239 | +5. *Memory as a Type System*: The 5 memory types aren't just storage categories — `Working` memory is explicitly non-persistent (disappears with the session), while `Shared` memory is explicitly cross-agent. This prevents accidental state leakage. |
| 240 | + |
| 241 | +== Roadmap |
| 242 | + |
| 243 | +=== Short-Term (v0.3.0) |
| 244 | + |
| 245 | +* [ ] *Session persistence*: Save/restore agent sessions across restarts (currently in-memory only) |
| 246 | +* [ ] *OODA metrics*: Track average time per phase, loop completion rate, halt frequency |
| 247 | +* [ ] *WebSocket state streaming*: Subscribe to specific session IDs for targeted monitoring |
| 248 | +* [ ] *Tool call logging*: Record every tool invocation with timestamp, inputs, outputs, safety check result |
| 249 | +* [ ] *MQTT retained messages*: Last-known state available to new subscribers |
| 250 | + |
| 251 | +=== Medium-Term (v0.4.0) |
| 252 | + |
| 253 | +* [ ] *Plan execution engine*: The 7 `PlanStep` types (Action, Condition, Loop, Branch, Parallel, Checkpoint, Rollback) become executable — agents submit plans, Agent-MCP validates and executes them step by step |
| 254 | +* [ ] *Agent capability model*: Define what tools each agent is allowed to use (per-session capability sets) |
| 255 | +* [ ] *Cross-session coordination*: Agents in different sessions can coordinate without sharing state (message-passing only) |
| 256 | +* [ ] *Rollback support*: If an `Act` fails, automatically roll back to the last `Checkpoint` in the plan |
| 257 | +* [ ] *GraphQL subscriptions*: Real-time OODA state changes via GraphQL subscription |
| 258 | +* [ ] *Cap'n Proto streaming*: Bidirectional streaming for high-throughput swarm coordination |
| 259 | + |
| 260 | +=== Long-Term (v1.0) |
| 261 | + |
| 262 | +* [ ] *Formal verification of coordination*: Prove that `Consensus` coordination never deadlocks and always terminates (using Idris2 totality checker) |
| 263 | +* [ ] *Agent identity and attestation*: Each agent cryptographically signs its OODA transitions, creating a tamper-proof audit trail |
| 264 | +* [ ] *OODA composition*: Nest OODA loops — an `Act` phase can contain a sub-OODA cycle for fine-grained decision-making |
| 265 | +* [ ] *Temporal logic properties*: Prove liveness (agents always eventually act) and safety (agents never act without deciding) using CTL model checking |
| 266 | +* [ ] *Agent marketplace*: Community-contributed agent templates with pre-defined OODA patterns, tool call sets, and coordination strategies |
| 267 | +* [ ] *Cross-cartridge agent workflows*: Agent-MCP orchestrates multi-cartridge workflows (e.g., agent uses NeSy-MCP for decision verification, Database-MCP for data access, Git-MCP for code changes — all within a single OODA loop) |
| 268 | +* [ ] *Self-improving agents*: Agents analyse their own OODA loop performance and suggest optimisations to their observation and orientation strategies |
| 269 | + |
| 270 | +=== Protocol Evolution |
| 271 | + |
| 272 | +* [ ] *HTTP/2 native gRPC*: Upgrade from JSON-over-HTTP to full Protobuf transport via Zig FFI |
| 273 | +* [ ] *QUIC transport*: UDP-based low-latency transport for swarm gossip |
| 274 | +* [ ] *NATS/JetStream*: Cloud-native messaging for distributed agent coordination |
| 275 | +* [ ] *OpenTelemetry integration*: Emit OODA transitions as OTel spans with distributed trace context |
| 276 | +* [ ] *MCP native transport*: Direct MCP stdio bridge without HTTP intermediary |
| 277 | +* [ ] *Agent-to-Agent protocol*: Purpose-built binary protocol for direct agent communication without broker overhead |
0 commit comments