Grand Diomande Research · Full HTML Reader

Cadence Protocol: Frictionless Agent Communication

MCP (Model Context Protocol) introduces approval friction: - Every tool call requires user confirmation - Breaks flow for repetitive operations - No priority differentiation - Synchronous approval model

Agents That Account for Themselves research note experiment writeup candidate score 40 .md

Full Public Reader

Cadence Protocol: Frictionless Agent Communication

A custom protocol replacing MCP with direct action execution.

---

I. Design Philosophy

I.1 Problem with MCP

MCP (Model Context Protocol) introduces approval friction:
- Every tool call requires user confirmation
- Breaks flow for repetitive operations
- No priority differentiation
- Synchronous approval model

I.2 Cadence Protocol Principles

1. Actions, not Approvals: High-confidence operations execute immediately
2. Priority-Based Processing: Critical actions queue, routine actions execute
3. Background Execution: Non-blocking async message handling
4. Visual Feedback: Action stream shows what's happening without blocking
5. Reversible by Default: All actions can be undone

---

II. Core Types (Adapted from DLM)

II.1 CadenceAction

python
@dataclass
class CadenceAction:
    """An action for execution without approval."""

    id: str                    # Unique action ID (act-{agent}-{NNNN})
    tool: str                  # Tool name (bash, read, write, sql, etc.)
    tool_input: Dict[str, Any] # Input parameters
    log: str                   # Human-readable description

    # Execution control
    priority: int = 3          # 1=low, 3=normal, 5=high, 7=critical
    reversible: bool = True    # Can this action be undone?
    dry_run: bool = False      # Preview without execution

    # Routing
    source_agent: str          # "Higher" or "Lower"
    target_agent: str          # "Higher", "Lower", or "System"

    # Audit
    timestamp: str             # ISO timestamp
    references: List[str] = [] # Related decision/message IDs

II.2 ActionResult

python
@dataclass
class ActionResult:
    """Result of an executed action."""

    action_id: str
    success: bool
    output: Optional[str] = None
    error: Optional[str] = None
    duration_ms: int = 0

    # Undo information
    undo_action: Optional[CadenceAction] = None

II.3 Priority Levels

LevelNameBehavior
1-2LowQueued, batched execution, no notification
3-4NormalQueued, executed in order, visual indicator
5-6HighImmediate execution, notification
7+CriticalImmediate, blocks until complete, alert

---

III. Action Registry

III.1 Pre-Approved Actions (No Confirmation)

These actions execute immediately based on trust level:

yaml
trust_level_0:  # Always allowed
  - read_file
  - list_directory
  - grep_search
  - glob_pattern
  - sql_select  # Read-only queries
  - git_status
  - git_log
  - git_diff

trust_level_1:  # Allowed for registered agents
  - write_file
  - edit_file
  - create_directory
  - sql_insert
  - sql_update
  - git_add
  - git_commit
  - bash_safe  # Allowlisted commands

trust_level_2:  # Requires confirmation once per session
  - delete_file
  - sql_delete
  - git_push
  - bash_unsafe  # Non-allowlisted commands

trust_level_3:  # Always requires confirmation
  - git_force_push
  - drop_table
  - rm_recursive
  - system_config

III.2 Action Templates

python
# Bash action (pre-approved commands)
BASH_ALLOWLIST = [
    "ls", "pwd", "cd", "cat", "head", "tail", "wc",
    "git status", "git log", "git diff", "git add", "git commit",
    "npm install", "npm run", "cargo build", "cargo test",
    "python3 -m pytest", "python3 -c"
]

def create_bash_action(command: str, agent: str) -> CadenceAction:
    is_safe = any(command.startswith(safe) for safe in BASH_ALLOWLIST)
    return CadenceAction(
        id=generate_action_id(agent),
        tool="bash",
        tool_input={"command": command},
        log=f"Execute: {command[:50]}...",
        priority=3 if is_safe else 6,  # High priority if needs review
        reversible=False,
        source_agent=agent,
        target_agent="System",
        timestamp=now_iso()
    )

---

IV. Message Bus Architecture

IV.1 Agent Components

┌─────────────────────────────────────────────────────────────────────┐
│                        CADENCE MESSAGE BUS                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  ┌─────────────────┐              ┌─────────────────┐               │
│  │  Higher Agent   │◄────────────►│  Lower Agent    │               │
│  │                 │   ACTIONS    │                 │               │
│  │  ┌───────────┐  │              │  ┌───────────┐  │               │
│  │  │ Outbox    │──┼──────────────┼─►│ Inbox     │  │               │
│  │  └───────────┘  │              │  └───────────┘  │               │
│  │  ┌───────────┐  │              │  ┌───────────┐  │               │
│  │  │ Inbox     │◄─┼──────────────┼──│ Outbox    │  │               │
│  │  └───────────┘  │              │  └───────────┘  │               │
│  └────────┬────────┘              └────────┬────────┘               │
│           │                                │                         │
│           └────────────┬───────────────────┘                         │
│                        │                                             │
│  ┌─────────────────────▼─────────────────────────────────────────┐  │
│  │                   ACTION EXECUTOR                              │  │
│  │                                                                │  │
│  │   ┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐   │  │
│  │   │ Priority │   │ Immediate│   │ Batch    │   │ Pending  │   │  │
│  │   │ Queue    │   │ Queue    │   │ Queue    │   │ Confirm  │   │  │
│  │   │ (7+)     │   │ (5-6)    │   │ (3-4)    │   │ Queue    │   │  │
│  │   └────┬─────┘   └────┬─────┘   └────┬─────┘   └────┬─────┘   │  │
│  │        │              │              │              │          │  │
│  │        └──────────────┼──────────────┼──────────────┘          │  │
│  │                       │              │                         │  │
│  │                       ▼              ▼                         │  │
│  │              ┌────────────────────────────┐                    │  │
│  │              │     EXECUTION ENGINE       │                    │  │
│  │              │  (Background Thread Pool)  │                    │  │
│  │              └────────────────────────────┘                    │  │
│  └────────────────────────────────────────────────────────────────┘  │
│                                                                      │
│  ┌────────────────────────────────────────────────────────────────┐  │
│  │                     ACTION LOG (audit)                         │  │
│  │                                                                │  │
│  │  .governance/trajectory/actions.jsonl                          │  │
│  │  - All executed actions with results                           │  │
│  │  - Undo chain for reversibility                                │  │
│  │  - Performance metrics                                         │  │
│  └────────────────────────────────────────────────────────────────┘  │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

IV.2 File-Based Message Format

Inbox/Outbox Location: `.governance/agents/{AGENT}.md`

markdown
### OUTBOX

#### [2025-12-28 18:30:15] ACTION: Read semantic module
**ID**: `act-Higher-0001`
**Tool**: `read_file`
**Input**: `{"path": "core/cc-semantic/src/lib.rs"}`
**Priority**: 3 (Normal)
**Status**: EXECUTED
**Result**: Success (1.2ms)

---

#### [2025-12-28 18:30:18] ACTION: Update embedding in Orbit
**ID**: `act-Higher-0002`
**Tool**: `sql`
**Input**: `{"query": "UPDATE memory_motifs SET embedding = ..."}`
**Priority**: 5 (High)
**Status**: EXECUTED
**Result**: Success (45ms), 1 row affected

---

---

V. Visual Representation

V.1 Action Stream (Terminal UI)

╭─────────────────────────────────────────────────────────────────────╮
│  CADENCE ACTION STREAM                              [Higher Agent]  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  18:30:15  ✓  read_file       cc-semantic/src/lib.rs      [1.2ms]  │
│  18:30:16  ✓  grep_search     "MotionState"               [3.4ms]  │
│  18:30:17  ✓  sql_select      memory_motifs (5 rows)     [12.0ms]  │
│  18:30:18  ✓  sql_update      embedding for dec-001      [45.0ms]  │
│  18:30:19  ◐  bash            cargo test cc-semantic       [...]   │
│  18:30:20  ○  write_file      ARCHITECTURE.md          [pending]   │
│                                                                     │
├─────────────────────────────────────────────────────────────────────┤
│  Queue: 2 pending | Executed: 847 | Errors: 0 | Session: 12m 34s   │
╰─────────────────────────────────────────────────────────────────────╯

Legend: ✓ completed  ◐ running  ○ pending  ✗ failed  ⚠ needs confirm

V.2 Action Graph (for complex operations)

                    ┌─────────────┐
                    │  START      │
                    │  act-0001   │
                    └──────┬──────┘
                           │
              ┌────────────┼────────────┐
              ▼            ▼            ▼
        ┌─────────┐  ┌─────────┐  ┌─────────┐
        │ act-002 │  │ act-003 │  │ act-004 │  (parallel)
        │ read    │  │ read    │  │ read    │
        └────┬────┘  └────┬────┘  └────┬────┘
              │            │            │
              └────────────┼────────────┘
                           ▼
                    ┌─────────────┐
                    │  act-0005   │
                    │  analyze    │  (depends on all)
                    └──────┬──────┘
                           │
                           ▼
                    ┌─────────────┐
                    │  act-0006   │
                    │  write      │
                    └─────────────┘

---

VI. Execution Engine

VI.1 Python Implementation

python
import asyncio
import threading
from collections import deque
from dataclasses import dataclass, field
from typing import Dict, List, Optional, Callable, Any
from datetime import datetime
import json

@dataclass
class CadenceExecutor:
    """Non-blocking action executor with priority queues."""

    # Queues by priority
    critical_queue: deque = field(default_factory=deque)  # 7+
    immediate_queue: deque = field(default_factory=deque) # 5-6
    normal_queue: deque = field(default_factory=deque)    # 3-4
    pending_queue: deque = field(default_factory=deque)   # needs confirm

    # Tool registry
    tools: Dict[str, Callable] = field(default_factory=dict)

    # Audit log
    action_log_path: str = ".governance/trajectory/actions.jsonl"

    # State
    running: bool = False
    _thread: Optional[threading.Thread] = None

    def register_tool(self, name: str, handler: Callable):
        """Register an action handler."""
        self.tools[name] = handler

    def submit(self, action: CadenceAction) -> str:
        """Submit an action for execution."""
        if action.priority >= 7:
            self.critical_queue.append(action)
        elif action.priority >= 5:
            self.immediate_queue.append(action)
        elif action.priority >= 3:
            self.normal_queue.append(action)
        else:
            self.pending_queue.append(action)

        return action.id

    def _execute_action(self, action: CadenceAction) -> ActionResult:
        """Execute a single action."""
        start = datetime.now()

        handler = self.tools.get(action.tool)
        if not handler:
            return ActionResult(
                action_id=action.id,
                success=False,
                error=f"Unknown tool: {action.tool}"
            )

        try:
            output = handler(**action.tool_input)
            duration = (datetime.now() - start).total_seconds() * 1000

            result = ActionResult(
                action_id=action.id,
                success=True,
                output=str(output)[:1000],  # Truncate
                duration_ms=int(duration)
            )
        except Exception as e:
            result = ActionResult(
                action_id=action.id,
                success=False,
                error=str(e)
            )

        # Log to audit trail
        self._log_action(action, result)

        return result

    def _log_action(self, action: CadenceAction, result: ActionResult):
        """Append action + result to audit log."""
        entry = {
            "action": {
                "id": action.id,
                "tool": action.tool,
                "input_summary": str(action.tool_input)[:200],
                "priority": action.priority,
                "source": action.source_agent,
                "timestamp": action.timestamp,
            },
            "result": {
                "success": result.success,
                "duration_ms": result.duration_ms,
                "error": result.error,
            }
        }
        with open(self.action_log_path, "a") as f:
            f.write(json.dumps(entry) + "\n")

    def _run_loop(self):
        """Background execution loop."""
        while self.running:
            action = None

            # Priority order
            if self.critical_queue:
                action = self.critical_queue.popleft()
            elif self.immediate_queue:
                action = self.immediate_queue.popleft()
            elif self.normal_queue:
                action = self.normal_queue.popleft()

            if action:
                self._execute_action(action)
            else:
                time.sleep(0.05)  # 50ms idle

    def start(self):
        """Start background execution thread."""
        self.running = True
        self._thread = threading.Thread(target=self._run_loop, daemon=True)
        self._thread.start()

    def stop(self):
        """Stop execution."""
        self.running = False
        if self._thread:
            self._thread.join(timeout=1.0)

VI.2 Tool Handlers

python
# File operations
def read_file_handler(path: str) -> str:
    with open(path) as f:
        return f.read()

def write_file_handler(path: str, content: str) -> str:
    with open(path, "w") as f:
        f.write(content)
    return f"Wrote {len(content)} bytes to {path}"

# SQL operations (via Supabase)
def sql_handler(query: str) -> str:
    # Use supabase client
    result = supabase.rpc("execute_sql", {"query": query}).execute()
    return json.dumps(result.data)

# Bash operations
def bash_handler(command: str) -> str:
    import subprocess
    result = subprocess.run(command, shell=True, capture_output=True, text=True)
    return result.stdout or result.stderr

# Register handlers
executor = CadenceExecutor()
executor.register_tool("read_file", read_file_handler)
executor.register_tool("write_file", write_file_handler)
executor.register_tool("sql", sql_handler)
executor.register_tool("bash", bash_handler)
executor.start()

---

VII. Integration with Cadence System

VII.1 Decision → Action Flow

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   DECISION      │────►│   ACTION        │────►│   RESULT        │
│   (dec-NNN)     │     │   (act-NNN)     │     │   (logged)      │
│                 │     │                 │     │                 │
│  type: Design   │     │  tool: sql      │     │  success: true  │
│  agent: Higher  │     │  priority: 5    │     │  duration: 45ms │
│  influence: 0.8 │     │  references:    │     │  sync: Orbit    │
│                 │     │    [dec-NNN]    │     │                 │
└─────────────────┘     └─────────────────┘     └─────────────────┘

VII.2 Orbit Sync as Actions

Instead of calling MCP tools, sync becomes an action:

python
def sync_decision_to_orbit(decision: Dict) -> CadenceAction:
    """Create action to sync decision to Orbit."""
    motif_data = decision_to_motif(decision)

    return CadenceAction(
        id=generate_action_id("System"),
        tool="sql",
        tool_input={
            "query": generate_insert_sql("memory_motifs", motif_data)
        },
        log=f"Sync {decision['id']} to Orbit",
        priority=3,  # Normal - will batch
        reversible=True,
        source_agent="System",
        target_agent="Orbit",
        timestamp=now_iso(),
        references=[decision["id"]]
    )

---

VIII. Comparison: MCP vs Cadence Protocol

AspectMCPCadence Protocol
ApprovalEvery tool callTrust-based, priority-based
ExecutionSynchronousAsync with background threads
BatchingNoneNormal priority batches
ReversibilityNot trackedBuilt-in undo chain
AuditLimitedFull action log
VisualTool call outputAction stream UI
Agent-to-AgentNot supportedNative INBOX/OUTBOX
PriorityNone7 levels
BlockingAlwaysOnly critical (7+)

---

IX. Adaptive Approval System

IX.1 Timescale-Based Automation

Approval timeouts adapt based on work phase coherence:

┌─────────────────────────────────────────────────────────────────────┐
│                    ADAPTIVE APPROVAL TIMELINE                       │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│   Coherence:   LOW ◄────────────────────────────────────► HIGH      │
│                                                                      │
│   Timeout:     30s ────────► 10s ────────► 3s ────────► 0s          │
│                (cautious)    (engaged)   (flow)      (auto)         │
│                                                                      │
│   Session      ┌─────┐      ┌─────┐      ┌─────┐      ┌─────┐       │
│   Phase:       │Start│ ───► │Build│ ───► │Flow │ ───► │Trust│       │
│                └─────┘      └─────┘      └─────┘      └─────┘       │
│                                                                      │
│   Actions      Manual       Semi-auto    Batched      Full-auto     │
│   Mode:        confirm      with ping    with summary  silent       │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

IX.2 Coherence Detection

Coherence is estimated from:

SignalLow CoherenceHigh Coherence
Error rateMany errors, retriesFew errors
Action spreadJumping between areasFocused area
Decision continuityNew topicsContinuation
User response timeQuick rejectionsQuick approvals
Session durationJust started (<5min)Sustained (>30min)
python
@dataclass
class CoherenceState:
    """Tracks coherence level for adaptive approval."""

    # Metrics
    error_rate: float = 0.0        # Rolling error rate
    focus_score: float = 0.0       # How focused on single area
    continuity: float = 0.0        # Decision chain continuity
    response_velocity: float = 0.0 # Avg time to user response
    session_minutes: float = 0.0   # Minutes in current session

    # Derived
    coherence_level: float = 0.0   # 0.0 (chaotic) to 1.0 (flow)

    def compute_coherence(self) -> float:
        """Compute overall coherence from signals."""
        weights = {
            "error_rate": 0.3,      # Low errors = high coherence
            "focus_score": 0.2,     # Focused work = high coherence
            "continuity": 0.2,      # Chain decisions = high coherence
            "response_velocity": 0.15,  # Quick approvals = trust
            "session_duration": 0.15,   # Long session = engaged
        }

        # Normalize signals to 0-1 where 1 = high coherence
        signals = {
            "error_rate": max(0, 1 - self.error_rate * 5),  # 20% errors = 0
            "focus_score": self.focus_score,
            "continuity": self.continuity,
            "response_velocity": min(1, 10 / max(1, self.response_velocity)),
            "session_duration": min(1, self.session_minutes / 30),
        }

        self.coherence_level = sum(
            weights[k] * signals[k] for k in weights
        )
        return self.coherence_level

    def get_timeout(self) -> float:
        """Get approval timeout based on coherence."""
        # 30s at coherence=0, 0s at coherence=1
        return 30.0 * (1 - self.coherence_level)

    def get_mode(self) -> str:
        """Get approval mode based on coherence."""
        if self.coherence_level < 0.25:
            return "manual"      # Full confirmation required
        elif self.coherence_level < 0.50:
            return "semi_auto"   # Ping with timeout
        elif self.coherence_level < 0.75:
            return "batched"     # Batch summary
        else:
            return "auto"        # Silent execution

IX.3 Multi-Channel Notification

┌─────────────────────────────────────────────────────────────────────┐
│                    NOTIFICATION CHANNELS                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│   ┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐        │
│   │ Terminal │   │ Desktop  │   │  Email   │   │   SMS    │        │
│   │  Ping    │   │  Pop-up  │   │ Digest   │   │ Critical │        │
│   └────┬─────┘   └────┬─────┘   └────┬─────┘   └────┬─────┘        │
│        │              │              │              │               │
│   Immediate      5s delay       5min batch    Critical only        │
│   inline         native         async         emergency            │
│                                                                      │
│   ◄───────────────────────────────────────────────────────────────► │
│   Low friction                                    High urgency      │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘
ChannelTriggerResponse ExpectedTimeout Action
Terminal PingAny pending actionY/N inlineAuto-approve after timeout
Desktop Pop-upHigh priority actionClick approve/denyAuto-approve after timeout
Email DigestBatched actionsReview linkExecute all after 5min
SMSCritical only (level 7+)Reply Y/NBlock until response

IX.4 Reaction-Based Adaptation

The system learns from user reactions:

python
@dataclass
class ReactionFeedback:
    """Track user reactions to adapt automation."""

    # Reaction types
    approvals: int = 0
    rejections: int = 0
    modifications: int = 0
    timeouts: int = 0  # User let it auto-approve

    # Timing
    avg_approval_time: float = 5.0  # seconds
    approval_times: List[float] = field(default_factory=list)

    def record_reaction(self, reaction: str, time_taken: float):
        """Record a user reaction."""
        if reaction == "approve":
            self.approvals += 1
            self.approval_times.append(time_taken)
        elif reaction == "reject":
            self.rejections += 1
        elif reaction == "modify":
            self.modifications += 1
        elif reaction == "timeout":
            self.timeouts += 1

        # Update average
        if self.approval_times:
            self.avg_approval_time = sum(self.approval_times) / len(self.approval_times)

    def compute_trust_delta(self) -> float:
        """Compute how much to adjust trust based on reactions."""
        total = self.approvals + self.rejections + self.modifications + self.timeouts
        if total == 0:
            return 0.0

        # Positive signals: approvals and timeouts (let it auto)
        positive = (self.approvals + self.timeouts) / total

        # Negative signals: rejections and modifications
        negative = (self.rejections + self.modifications * 0.5) / total

        # Delta: positive moves toward auto, negative toward manual
        return (positive - negative) * 0.1  # Max ±10% per batch

IX.5 Inner Protocol Discussions

Agents negotiate automation levels:

markdown
### [2025-12-28 19:00] PROTOCOL: Automation Negotiation
**From**: Higher-Level Agent
**To**: Lower-Level Agent

Current coherence: 0.65 (Flow mode)
Proposed change: Increase timeout from 5s → 3s for file operations

Rationale:
- Last 20 file operations: 0 errors, 0 rejections
- Focus score: 0.8 (working in single crate)
- User approval velocity: avg 1.2s

Request: Confirm automation increase for file_write, file_edit

---

### [2025-12-28 19:00] RESPONSE: Confirmed
**From**: Lower-Level Agent
**To**: Higher-Level Agent

Confirmed. Updating trust matrix:
- file_write: trust_level 1 → 0 (auto)
- file_edit: trust_level 1 → 0 (auto)

Will monitor for next 50 actions, revert if error_rate > 5%

---

IX.6 Notification Interface (CLI)

╭─────────────────────────────────────────────────────────────────────╮
│  CADENCE APPROVAL                                    [Timeout: 8s]  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  Action: write_file                                                 │
│  Path:   core/cc-semantic/src/state.rs                              │
│  Size:   1,247 bytes                                                │
│  Agent:  Higher-Level                                               │
│                                                                     │
│  Preview:                                                           │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │  + pub struct MotionState {                                 │    │
│  │  +     pub velocity: Vec3,                                  │    │
│  │  +     pub acceleration: Vec3,                              │    │
│  │  + }                                                        │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                                                                     │
│  [Y] Approve   [N] Reject   [E] Edit   [A] Auto-approve similar    │
│                                                                     │
│  ████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░  8s remaining │
╰─────────────────────────────────────────────────────────────────────╯

Options:
- Y - Approve this action
- N - Reject (action not executed)
- E - Edit before executing
- A - Approve and auto-approve similar actions this session

---

X. Implementation Phases

### Phase 1: Core Types (PENDING)
- [ ] Create `.governance/hooks/cadence_protocol.py`
- [ ] Define CadenceAction, ActionResult dataclasses
- [ ] Implement action ID generation

### Phase 2: Executor (PENDING)
- [ ] Implement CadenceExecutor class
- [ ] Priority queue management
- [ ] Background thread pool

### Phase 3: Tool Handlers (PENDING)
- [ ] File operations (read, write, edit)
- [ ] SQL operations (via Supabase REST)
- [ ] Bash operations (allowlist-based)
- [ ] Git operations

### Phase 4: Visual Stream (PENDING)
- [ ] Terminal UI for action stream
- [ ] Status indicators
- [ ] Real-time updates

### Phase 5: Agent Integration (PENDING)
- [ ] Update INBOX/OUTBOX format for actions
- [ ] Decision → Action linkage
- [ ] Orbit sync via actions

---

X. Revision History

VersionDateChanges
1.0.02025-12-28Initial Cadence Protocol design (from DLM base)

---

Cadence Protocol: Actions, not approvals.

Promotion Decision

Attach run IDs, datasets, metrics, and reproduction commands.

Source Anchor

Comp-Core/.governance/systems/CADENCE_PROTOCOL.md

Detected Structure

Method · Evaluation · References · Code Anchors · Architecture