synod-cli 2.6.1
AI coding agent with adversarial debate. Multiple models critique each other, only battle-tested answers survive. Infinite memory that never forgets.
License: MIT
Requires Python: >=3.8
Keywords: adversarial-debate, ai, claude, cli, code-review, coding-agent, coding-assistant, gemini, gpt, llm, memory, multi-model

# Synod

[![PyPI version](https://badge.fury.io/py/synod-cli.svg)](https://badge.fury.io/py/synod-cli)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)

**Ancient Councils. Modern Intelligence.**

> *The coding agent where models argue and one learns to rule.*

**Collective intelligence for code. Not consensus — synthesis.**

[Website](https://synod.run) | [Dashboard](https://synod.run/dashboard) | [PyPI](https://pypi.org/project/synod-cli/)

---

<div align="center">

### Why Synod?

**Single-model agents hallucinate. Synod debates until the wrong idea dies.**

| Problem | Synod Solution |
|---------|----------------|
| Single AI hallucinates | **Multiple models catch each other's mistakes** |
| Context limits run out | **Infinite memory that never forgets** |
| No memory between sessions | **Battle-tested insights persist forever** |
| Can't trust AI suggestions | **Every answer survives adversarial review** |

</div>

---

## The Philosophy

*The future isn't bigger models — it's collective reasoning.*

Why pick a model when you can orchestrate all of them?

For centuries, the most important decisions weren't made by a single authority. They were forged through **structured debate**. In ecclesiastical councils (called *synods*), bishops would gather, propose, critique, and challenge each other. Only after rigorous discourse would the presiding authority synthesize a final judgment.

We built Synod on the same principle. Models converge. Orchestration compounds.

## What is Synod?

Synod is a CLI coding agent that orchestrates **adversarial debates** among multiple AI models.

Instead of asking one AI and hoping it doesn't hallucinate, Synod convenes a council:

- **Bishops** (Claude, GPT-4, Gemini, Grok, DeepSeek, GLM) independently propose solutions
- Each Bishop **critiques the others**, hunting for bugs, edge cases, and flaws
- The **Pope** observes silently, learns from the debate, then synthesizes the answer

The Pope doesn't pick a winner. It distills the best concepts into something better than any single proposal. **Not consensus — synthesis.**

## Quick Start

```bash
# Install (recommended)
pipx install synod-cli

# Or with pip
pip install synod-cli

# Login (opens browser)
synod login

# Start coding
synod
```

That's it. No API keys to copy, no configuration files.

> **Tip:** Use `pipx` for CLI tools — it installs in isolated environments and makes upgrades easy with `pipx upgrade synod-cli`

### Headless Servers (SSH / No Browser)

Synod auto-detects headless environments (SSH sessions, missing DISPLAY) and switches to manual authentication:

```bash
# On a headless server, this auto-uses manual mode
synod login

# Or explicitly use manual mode anywhere
synod login --manual
```

Manual mode prompts you to:
1. Visit https://synod.run/dashboard/settings on any device
2. Click "Generate API Key" in the CLI Sessions section
3. Copy the key and paste it into the terminal

**Environment variable control:**
```bash
# Force headless mode (manual auth)
export SYNOD_HEADLESS=1

# Force browser mode (override auto-detection)
export SYNOD_HEADLESS=0
```

## How It Works

```
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   You: "How do I implement rate limiting?"                  │
│                                                             │
│                         ↓                                   │
│                                                             │
│   ┌─────────┐  ┌─────────┐  ┌─────────┐                     │
│   │ Bishop  │  │ Bishop  │  │ Bishop  │   Stage 1:          │
│   │ Claude  │  │  GPT-4  │  │ Gemini  │   Proposals         │
│   └────┬────┘  └────┬────┘  └────┬────┘                     │
│        │            │            │                          │
│        └────────────┼────────────┘                          │
│                     ↓                                       │
│        ┌────────────────────────┐                           │
│        │   Adversarial Debate   │   Stage 2:                │
│        │   Models critique      │   Critiques               │
│        │   each other's code    │                           │
│        └───────────┬────────────┘                           │
│                    ↓                                        │
│        ┌────────────────────────┐                           │
│        │    Pope Synthesis      │   Stage 3:                │
│        │   Observes, learns,    │   Informed Synthesis      │
│        │   distills the answer  │                           │
│        └────────────────────────┘                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

### The Debate Process

**Stage 0: Classification**
Before convening the council, Synod analyzes your query. Trivial questions get fast answers. Complex problems get full debates.

**Stage 1: Bishop Proposals**
Multiple AI models independently propose solutions in parallel. Each brings different strengths: Claude for reasoning, GPT for breadth, DeepSeek for algorithms.

**Stage 2: Adversarial Critiques**
Each Bishop acts as a Staff Engineer conducting an *adversarial* code review:
- **Security**: Injection, auth bypass, data exposure
- **Correctness**: Bugs, edge cases, race conditions
- **Performance**: O(n²) traps, memory leaks, unbounded growth
- **Production-readiness**: Error handling, logging, observability

**Smart Dynamic Rounds**: Synod uses intelligent exit conditions:

| Complexity | Max Rounds | Early Exit Conditions |
|------------|-----------|----------------------|
| trivial | 0 (skip) | — |
| simple | 1 | — |
| moderate | 2 | High consensus + no critical issues |
| complex | 2 | Only minor issues found |
| expert | 3 | Issues resolved/decreasing |

The CLI shows exactly why debate concluded:
```
✓ Debate concluded early (round 1/2)
   → High consensus (87%) with no critical issues.
   Issues: 🔴 0 critical  🟡 2 moderate  🟢 3 minor
```

**Stage 3: Pope Synthesis**
The Pope is a neutral observer. It hardly participates during debate, staying unbiased. After models argue, it synthesizes — not by picking a winner, but by distilling the best concepts into something new.

The Pope catches when all models agreed on the wrong approach. Consensus can be collective blindness. That's why there's a Pope.

## Adversarial Memory

Synod memories are **verified by multiple AI models before storage**. Every insight survives debate before it's remembered.

```
┌─────────────────────────────────────────────────────────────┐
│  Synod Adversarial Memory:                                  │
│                                                             │
│    Claude ──┐                                               │
│    GPT ─────┼→ Critique each other → Pope verifies → Store  │
│    Gemini ──┘                                               │
│                                                             │
│  Context never dies. Infinite memory. Infinite context.     │
└─────────────────────────────────────────────────────────────┘
```

**Why it matters:**
- Memories from high-consensus debates get higher confidence scores
- Insights that survived adversarial critique are more trustworthy
- Skills are only learned when multiple models agreed on the approach
- Automatic decay removes stale memories over time
- Cross-project learning from your coding patterns

**What Synod remembers:**

| Memory Type | Scope | Examples |
|-------------|-------|----------|
| `preference` | User | "Prefers TypeScript over JavaScript" |
| `pattern` | User | "Often uses async/await over .then()" |
| `fact` | User | "Familiar with React and Next.js" |
| `correction` | User | "Corrected: use useState not useRef" |
| `skill` | User (Pro+) | Reusable patterns from successful debates |
| `architecture` | Project | "Uses microservices with API gateway" |
| `convention` | Project | "Uses snake_case for database fields" |
| `bug` | Project | "Auth middleware has race condition" |
| `decision` | Project | "Chose PostgreSQL for ACID compliance" |

**Skills (Pro+ only):**
Skills are reusable patterns extracted from high-quality debates:
- Only extracted when consensus ≥ 70% AND no critical issues
- Stored with higher deduplication threshold (0.90)
- Automatically suggested for similar future problems

**Memory Commands:**
```bash
synod> /memory           # View memory dashboard
synod> /memory show      # Display local context files
synod> /memory graph     # Visualize memory connections (Pro)
synod> /memory timeline  # Show memory activity over time
```

## Features

### Multi-Model Debate
- **6 AI providers**: Anthropic, OpenAI, Google, xAI, DeepSeek, Zhipu
- **Adversarial critiques** catch errors single models miss
- **Pope synthesis** — not consensus, synthesis
- **Answers that survive hostile code review**

### Infinite Memory & Context
- **Context never dies**: Semantic memory that grows with you
- **Cross-project learning**: Patterns from one project help another
- **Verified memories**: Only insights that survived debate get stored
- **Confidence scoring**: High-consensus memories ranked higher
- **Smart retrieval**: Only relevant memories injected (no token waste)

### Smart & Fast
- **Intelligent routing**: Trivial questions get fast answers, complex problems get full debates
- **Smart dynamic rounds**: Complexity-based round caps with intelligent early exit
- **Issue-aware exit**: Critical issues force continued debate, minor issues allow early exit
- **Parallel execution**: All bishops propose simultaneously
- **Token efficiency**: Pay for intelligence, not repetition

### Privacy-First (Zero Storage)
- **Nothing is saved**: Your queries and code are never stored on our servers
- **Pass-through only**: Data flows to AI providers and back, then it's gone
- **Memories are semantic**: Only extracted insights stored as embeddings (not raw text)
- **BYOK available**: Your API keys are encrypted at rest, never logged
- **[Read our Privacy Policy](https://synod.run/privacy)**: Our commitment to your data

### Beautiful CLI
- Real-time streaming with rich formatting
- Animated debate stages
- Interactive REPL mode

### Project Context (SYNOD.md)
Like Claude Code's CLAUDE.md, Synod reads project instructions from:
- `.synod/SYNOD.md` - Project-specific guidelines (commit to git)
- `.synod/SYNOD.local.md` - Local preferences (gitignored)
- `~/.synod/SYNOD.md` - User-wide preferences

```bash
synod> /init          # Create .synod/SYNOD.md
synod> /memory        # View loaded context
synod> /memory show   # Display full context
```

### Custom Slash Commands
Create reusable prompts as markdown files:

```bash
# Create .synod/commands/review.md
---
description: Run security review
---
Review this code for security vulnerabilities: $ARGUMENTS
```

Then use it: `synod> /review src/auth.py`

Supports `$ARGUMENTS`, `$1`, `$2` for argument interpolation.

### Git Integration
AI-powered git workflow:

```bash
synod> /diff          # Show git status and diff preview
synod> /commit        # Stage files, debate-generated commit message, push option
synod> /pr            # Create PR with debate-synthesized description (requires gh)
```

**How `/commit` works:**
1. Shows staged/unstaged files
2. Offers to stage all if nothing staged
3. Runs a debate to generate a conventional commit message
4. Shows message for confirmation
5. Creates commit and offers to push

**How `/pr` works:**
1. Gets commits and diff vs main/master
2. Runs a debate to generate PR title and description
3. Pushes branch and creates PR via GitHub CLI

### Adversarial Code Review
Run adversarial review on PRs, diffs, or files:

```bash
# CLI commands
synod review --pr 123   # Review PR #123 (requires gh)
synod review --diff     # Review uncommitted changes

# Interactive mode commands
synod> /review 123        # Review PR #123 (requires gh)
synod> /review file.py    # Review a specific file
synod> /critique a.py b.py  # Critique multiple files
```

**Requirements:**
- `/diff`, `/commit` - Just needs `git`
- `/pr`, `/review <pr-number>`, `synod review --pr` - Requires [GitHub CLI (gh)](https://cli.github.com)

### Hooks System

Automate workflows with hooks (like git hooks, but for AI). Hooks are shell commands that run at specific events.

```json
// .synod/hooks.json
{
  "hooks": [
    {
      "name": "run-tests-after-debate",
      "event": "post_debate",
      "command": "npm test 2>/dev/null || echo 'Tests skipped'"
    },
    {
      "name": "format-on-edit",
      "event": "file_modified",
      "command": "npx prettier --write \"$SYNOD_FILE\" 2>/dev/null"
    },
    {
      "name": "block-env-edits",
      "event": "pre_tool_use",
      "command": "if [[ \"$SYNOD_FILE\" =~ \\.env ]]; then echo '{\"allow\": false, \"message\": \"Cannot edit .env files\"}'; fi"
    }
  ]
}
```

#### Hook Events

| Event | When it fires | Can block? | Use case |
|-------|--------------|------------|----------|
| `session_start` | Session begins | No | Setup, notifications |
| `session_end` | Session ends | No | Cleanup, reports |
| `pre_debate` | Before AI debate starts | Yes | Validation, preprocessing |
| `post_debate` | After AI debate completes | No | Tests, notifications |
| `pre_tool_use` | Before any tool executes | Yes | Block dangerous operations |
| `post_tool_use` | After any tool executes | No | Logging, side effects |
| `file_modified` | After a file is created/edited | No | Formatting, linting |

#### Environment Variables

Hooks receive context via environment variables:

| Variable | Description | Available in |
|----------|-------------|--------------|
| `SYNOD_EVENT` | The event type | All hooks |
| `SYNOD_WORKING_DIR` | Current working directory | All hooks |
| `SYNOD_QUERY` | User's query | `pre_debate`, `post_debate` |
| `SYNOD_TOOL` | Tool being executed | `*_tool_use` hooks |
| `SYNOD_TOOL_PARAMS` | JSON params for tool | `pre_tool_use` |
| `SYNOD_TOOL_RESULT` | Tool output (truncated) | `post_tool_use` |
| `SYNOD_FILE` | File being modified | `file_modified`, `*_tool_use` |

#### Blocking Hooks

`pre_tool_use` and `pre_debate` hooks can block execution by returning JSON:

```bash
# Block .env file edits
echo '{"allow": false, "message": "Cannot edit .env files"}'
```

#### Hook Commands

```bash
synod> /hooks                  # List configured hooks
synod> /hooks add <n> <event> <command>
synod> /hooks remove <n>
```

Hooks are loaded from both `~/.synod/hooks.json` (user-level) and `.synod/hooks.json` (project-level).

### Checkpoint/Undo System

Automatic checkpoints are created before every file modification, enabling undo:

```bash
synod> /rewind            # Show available checkpoints (last 10)
synod> /rewind <id>       # Restore specific checkpoint
```

Checkpoints are stored in `.synod/checkpoints/` (auto-gitignored) and retain the last 20 states.

## Pricing

| Tier | Price | Debates/Day | Bishops | Memory |
|------|-------|-------------|---------|--------|
| Free | $0 | 10 | 3 | 1,000 memories (30-day retention) |
| Pro | $19/mo | Unlimited | 7 | Unlimited (forever) |
| Team | $49/mo | Unlimited | 7 + shared | Unlimited + shared team memory |

**BYOK Mode**: Bring your own API keys. You pay the providers directly, Synod just orchestrates.

## Commands

```bash
synod              # Start interactive session
synod login        # Authenticate (auto-detects headless)
synod login -m     # Manual API key entry (for servers)
synod logout       # Clear credentials
synod whoami       # Show current user
synod status       # Check account status
synod review --pr 123  # Adversarial PR review
synod review --diff    # Review uncommitted changes
synod --help       # All commands
```

### In Interactive Mode

```
synod> How do I implement a LRU cache?
synod> /help       # Show all commands
synod> /clear      # New conversation
synod> /exit       # Quit
```

### All Slash Commands

| Command | Description |
|---------|-------------|
| **Session** | |
| `/exit`, `/quit`, `/q` | Exit the session |
| `/clear`, `/reset`, `/new` | Clear conversation history |
| `/resume` | Load previous session |
| `/cost` | Show session cost |
| `/history` | View recent sessions |
| `/stats` | Detailed session statistics |
| `/compact` | Compact conversation history |
| `/rewind [id]` | Show checkpoints or restore one |
| **Git** | |
| `/diff` | Show git status and diff preview |
| `/commit [msg]` | Debate-generated commit message (or use provided) |
| `/pr [title]` | Create PR with debate description (requires `gh`) |
| **Review** | |
| `/review <file\|pr#>` | Review a file or PR number |
| `/critique <files...>` | Adversarial critique of files |
| **Testing** | |
| `/test` | Run project tests (auto-detects framework) |
| `/test -k <pattern>` | Run tests matching pattern (pytest) |
| **Memory** | |
| `/memory` | View memory dashboard |
| `/memory show` | Display local context files |
| `/memory graph` | Visualize memory connections (Pro) |
| `/memory timeline [days]` | Show memory activity timeline |
| **Configuration** | |
| `/config` | Open dashboard in browser |
| `/bishops`, `/pope` | Configure models (via web dashboard) |
| `/hooks` | List, add, or remove hooks |
| **Workspace** | |
| `/context` | Show context/token usage |
| `/index` | Re-index workspace files |
| `/files` | List indexed files |
| `/add <file>` | Add file to conversation context |
| `/search <query>` | Search codebase |
| `/init` | Create .synod/SYNOD.md |
| **General** | |
| `/help`, `/?` | Show all commands |
| `/version` | Show version |
| `/voice`, `/mic` | Speak your query instead of typing |

### Voice Input (Experimental)

Speak your queries instead of typing with `/voice`:

```bash
# Install voice dependencies
pip install synod-cli[voice]

# On macOS, you may also need:
brew install portaudio

# Then use voice in interactive mode
synod> /voice
Downloading Whisper model (base.en)...  # First time only (~140MB)
Recording... (speak now, pause to stop)
You said: How do I implement rate limiting?
# → Debate starts with your spoken query
```

Voice runs entirely locally using [faster-whisper](https://github.com/SYSTRAN/faster-whisper) - no API costs, works offline. Models are cached in `~/.cache/synod/whisper-models/`.

### Test Runner

Run your project's tests directly from Synod with `/test`:

```bash
synod> /test
Running Tests
Detected: pytest
Running: pytest -v --tb=short

tests/test_api.py::test_create_user PASSED
tests/test_api.py::test_rate_limit FAILED

Tests failed: 1 failed, 5 passed

Tip: Ask Synod to fix the failing tests

synod> fix the failing test
# → Synod analyzes the failure and fixes your code
```

**Supported frameworks:**
- **Python**: pytest, unittest
- **JavaScript/TypeScript**: jest, vitest, mocha, npm test
- **Go**: go test
- **Rust**: cargo test
- **Ruby**: rspec, minitest
- **PHP**: phpunit
- **Java**: maven, gradle

Pass extra arguments: `/test -k auth` → runs `pytest -v --tb=short -k auth`

## Security

### Workspace Trust

When you run `synod` in a directory, you'll be asked to trust the workspace:

```
Accessing workspace: /path/to/project

Safety check: Is this a project you created or trust?
The Council will be able to read, edit, and execute files here.

? Yes, I trust this workspace
  No, exit
```

**Only trust workspaces you control.** Synod can read and modify files in trusted workspaces.

### Data Privacy Promise

**We never store your queries or code. Ever.**

| What | Stored? | Details |
|------|---------|---------|
| Your queries | ❌ No | Pass-through to AI providers only |
| Your code | ❌ No | Never touches our servers |
| Conversation content | ❌ No | Discarded after response |
| Raw text | ❌ No | Only semantic embeddings for memory |
| API keys (BYOK) | 🔒 Encrypted | AES-256 at rest, never logged |
| Usage metadata | ✓ Yes | Token counts, timestamps (for billing) |

**Memory stores insights, not content.** When Synod "remembers" that you prefer TypeScript, it stores a semantic embedding of that preference, not your actual code or conversation.

Read our full [Privacy Policy](https://synod.run/privacy) for details.

### Credentials & Config Files

**User-level** (`~/.synod/`):
- `config.json` - API key and settings
- `SYNOD.md` - User-wide AI instructions
- `commands/` - Custom slash commands
- `hooks.json` - User-level hooks

**Project-level** (`.synod/`):
- `SYNOD.md` - Project guidelines (commit to git)
- `SYNOD.local.md` - Local preferences (gitignored)
- `commands/` - Project slash commands
- `hooks.json` - Project hooks
- `checkpoints/` - Auto-saved undo points

API key format: `sk_...`

### Environment Variables

| Variable | Description | Values |
|----------|-------------|--------|
| `SYNOD_HEADLESS` | Control headless detection | `1`/`true` = force manual auth, `0`/`false` = force browser |

Synod auto-detects headless environments (SSH sessions, missing `DISPLAY` on Linux) and switches to manual API key entry. Use `SYNOD_HEADLESS` to override this behavior.

## Architecture

```
┌─────────────────┐     ┌─────────────────────────────────────┐
│   Synod CLI     │────▶│          Synod Cloud                │
│  (This repo)    │◀────│  (api.synod.run)                    │
└─────────────────┘     │                                     │
                        │  ┌─────────────────────────────┐    │
                        │  │ Debate Orchestration        │    │
                        │  │ - Query classification      │    │
                        │  │ - Bishop selection          │    │
                        │  │ - Parallel proposals        │    │
                        │  │ - Adversarial critiques     │    │
                        │  │ - Pope synthesis            │    │
                        │  └─────────────────────────────┘    │
                        │                                     │
                        │  ┌─────────────────────────────┐    │
                        │  │ LLM Providers               │    │
                        │  │ Anthropic, OpenAI, Google,  │    │
                        │  │ xAI, DeepSeek, Zhipu        │    │
                        │  └─────────────────────────────┘    │
                        │                                     │
                        │  ┌─────────────────────────────┐    │
                        │  │ Memory System               │    │
                        │  │ Qdrant + Semantic Search    │    │
                        │  └─────────────────────────────┘    │
                        └─────────────────────────────────────┘
```

The CLI is a thin client. All debate orchestration happens in Synod Cloud.

## The Name

A **synod** (from Greek *σύνοδος*, "assembly") is a council convened to decide matters through structured debate. The Council of Nicaea in 325 AD brought together bishops from across the Roman Empire to debate and establish foundational doctrine.

We borrowed the model, not the religion:
- **Bishops**: Independent experts who propose and critique
- **Pope**: The neutral observer who synthesizes final judgment
- **Debate**: Adversarial discourse that stress-tests ideas

Ancient wisdom. Modern implementation.

## Development

```bash
# Clone
git clone https://github.com/KekwanuLabs/synod-cli.git
cd synod-cli

# Install with uv
uv sync
pip install -e .

# Run
synod
```

## Contributing

| Type | How |
|------|-----|
| Bug Reports | [Open an issue](https://github.com/KekwanuLabs/synod-cli/issues) |
| Feature Requests | [Open an issue](https://github.com/KekwanuLabs/synod-cli/issues) |
| Code | Fork → Branch → PR |

## License

MIT License - Free and open source.

Copyright (c) 2025 [KekwanuLabs](https://kekwanu.com)

---

<div align="center">

*Why pick a model when you can orchestrate all of them?*

**The future isn't bigger models — it's collective reasoning.**

*The council is always in session.*

**[synod.run](https://synod.run)**

[Report Bug](https://github.com/KekwanuLabs/synod-cli/issues) · [Request Feature](https://github.com/KekwanuLabs/synod-cli/issues) · [PyPI](https://pypi.org/project/synod-cli/)

</div>