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
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
@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 IDsII.2 ActionResult
@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] = NoneII.3 Priority Levels
| Level | Name | Behavior |
|---|---|---|
| 1-2 | Low | Queued, batched execution, no notification |
| 3-4 | Normal | Queued, executed in order, visual indicator |
| 5-6 | High | Immediate execution, notification |
| 7+ | Critical | Immediate, blocks until complete, alert |
---
III. Action Registry
III.1 Pre-Approved Actions (No Confirmation)
These actions execute immediately based on trust level:
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_configIII.2 Action Templates
# 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`
### 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 confirmV.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
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
# 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:
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
| Aspect | MCP | Cadence Protocol |
|---|---|---|
| Approval | Every tool call | Trust-based, priority-based |
| Execution | Synchronous | Async with background threads |
| Batching | None | Normal priority batches |
| Reversibility | Not tracked | Built-in undo chain |
| Audit | Limited | Full action log |
| Visual | Tool call output | Action stream UI |
| Agent-to-Agent | Not supported | Native INBOX/OUTBOX |
| Priority | None | 7 levels |
| Blocking | Always | Only 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:
| Signal | Low Coherence | High Coherence |
|---|---|---|
| Error rate | Many errors, retries | Few errors |
| Action spread | Jumping between areas | Focused area |
| Decision continuity | New topics | Continuation |
| User response time | Quick rejections | Quick approvals |
| Session duration | Just started (<5min) | Sustained (>30min) |
@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 executionIX.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 │
│ │
└─────────────────────────────────────────────────────────────────────┘| Channel | Trigger | Response Expected | Timeout Action |
|---|---|---|---|
| Terminal Ping | Any pending action | Y/N inline | Auto-approve after timeout |
| Desktop Pop-up | High priority action | Click approve/deny | Auto-approve after timeout |
| Email Digest | Batched actions | Review link | Execute all after 5min |
| SMS | Critical only (level 7+) | Reply Y/N | Block until response |
IX.4 Reaction-Based Adaptation
The system learns from user reactions:
@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 batchIX.5 Inner Protocol Discussions
Agents negotiate automation levels:
### [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
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2025-12-28 | Initial 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