# Tetrad: MCP de Consenso Quádruplo em Rust

> **Versão 2.0** - Revisada com aprendizados do Claude-Flow

## Sumário Executivo

**Tetrad** é um servidor MCP de alta performance escrito em Rust que orquestra três ferramentas CLI de código (Codex, Gemini CLI, Qwen Code) para avaliar e validar todo trabalho produzido pelo Claude Code. O sistema implementa um protocolo de consenso quádruplo onde nenhum código ou plano é aceito sem a aprovação unânime de quatro inteligências: os três avaliadores externos + o próprio Claude Code.

### Novidades v2.0 (Inspiradas no Claude-Flow)

| Feature | Descrição |
|---------|-----------|
| **ReasoningBank** | Sistema de aprendizado contínuo com ciclo RETRIEVE→JUDGE→DISTILL→CONSOLIDATE |
| **CLI Interativa** | Comandos `tetrad init`, `tetrad status`, `tetrad config` |
| **Distribuição crates.io** | `cargo install tetrad` para instalação global |
| **Sistema de Plugins** | Extensibilidade para novos avaliadores |
| **CLAUDE.md** | Documentação para o Claude Code usar automaticamente |
| **Hooks** | Callbacks para pre/post avaliação |
| **Persistência** | SQLite para histórico cross-session |

### Por que Rust?

| Aspecto | Benefício |
|---------|-----------|
| **Performance** | Execução paralela nativa com zero overhead de runtime |
| **Confiabilidade** | Sistema de tipos que previne bugs em tempo de compilação |
| **Concorrência** | Tokio async runtime para chamadas CLI simultâneas |
| **Binário único** | Deploy simples sem dependências de runtime |
| **Baixa latência** | Ideal para MCP que precisa responder rapidamente |
| **crates.io** | Distribuição fácil como o npm para Node.js |

---

## 1. Instalação e Uso (Como Claude-Flow)

### 1.1 Instalação Rápida

```bash
# Via cargo (recomendado)
cargo install tetrad

# Via Homebrew (macOS/Linux)
brew install tetrad

# Via binário direto (releases do GitHub)
curl -fsSL https://github.com/seu-usuario/tetrad/releases/latest/download/install.sh | sh
```

### 1.2 Inicialização

```bash
# Inicializa configuração no projeto atual
tetrad init

# Verifica status das CLIs
tetrad status

# Configura interativamente
tetrad config
```

### 1.3 Integração com Claude Code

```bash
# Adiciona como MCP server (similar ao Claude-Flow)
claude mcp add tetrad -- tetrad serve

# Ou manualmente em ~/.claude/settings.json
```

### 1.4 Comandos CLI Disponíveis

```
tetrad - CLI de Consenso Quádruplo para Claude Code

USAGE:
    tetrad <COMMAND>

COMMANDS:
    init        Inicializa configuração no diretório atual
    serve       Inicia o servidor MCP (usado pelo Claude Code)
    status      Mostra status das CLIs (codex, gemini, qwen)
    config      Configura opções interativamente
    evaluate    Avalia código manualmente (sem MCP)
    history     Mostra histórico de avaliações
    export      Exporta ReasoningBank para arquivo
    import      Importa patterns de outro ReasoningBank
    doctor      Diagnostica problemas de configuração
    version     Mostra versão

OPTIONS:
    -c, --config <FILE>    Arquivo de configuração (default: tetrad.toml)
    -v, --verbose          Modo verbose
    -q, --quiet            Modo silencioso
    -h, --help             Mostra ajuda
```

---

## 2. Arquitetura do Sistema

### 2.1 Visão Geral (Atualizada)

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                              CLAUDE CODE                                     │
│                      (Gerador de Código + Decisor Final)                     │
└───────────────────────────────┬─────────────────────────────────────────────┘
                                │ MCP Protocol (stdio)
                                ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                       MCP SERVER: TETRAD (Rust)                              │
│                                                                              │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │                           ORQUESTRADOR                                  │ │
│  │  • Recebe requisições MCP do Claude Code                               │ │
│  │  • Gerencia pipeline de gates (Plan → Impl → Tests)                    │ │
│  │  • Coordena loop de refinamento até consenso                           │ │
│  │  • Consulta ReasoningBank para patterns conhecidos                     │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
│                                │                                             │
│          ┌─────────────────────┼─────────────────────┐                      │
│          ▼                     ▼                     ▼                      │
│  ┌──────────────┐     ┌──────────────┐     ┌──────────────┐                │
│  │    CODEX     │     │    GEMINI    │     │     QWEN     │                │
│  │   Executor   │     │   Executor   │     │   Executor   │                │
│  │              │     │              │     │              │                │
│  │ CLI: codex   │     │ CLI: gemini  │     │ CLI: qwen    │                │
│  │ Flag: -p     │     │ --output-    │     │ Flag: -p     │                │
│  │              │     │ format json  │     │              │                │
│  └──────────────┘     └──────────────┘     └──────────────┘                │
│          │                     │                     │                      │
│          └─────────────────────┼─────────────────────┘                      │
│                                ▼                                             │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │                       MOTOR DE CONSENSO                                 │ │
│  │  • Coleta votos (PASS/WARN/FAIL) de cada CLI                           │ │
│  │  • Aplica regras: Regra de Ouro, Consenso Fraco/Forte                  │ │
│  │  • Calcula score agregado e confidence                                 │ │
│  │  • Gera feedback consolidado e acionável                               │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
│                                │                                             │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │                     REASONING BANK (SQLite)                             │ │
│  │                                                                         │ │
│  │  ┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────────┐        │ │
│  │  │ RETRIEVE │──▶│  JUDGE   │──▶│ DISTILL  │──▶│ CONSOLIDATE  │        │ │
│  │  │          │   │          │   │          │   │              │        │ │
│  │  │ Busca    │   │ Avalia   │   │ Extrai   │   │ Previne      │        │ │
│  │  │ patterns │   │ sucesso/ │   │ learnings│   │ esquecimento │        │ │
│  │  │ similares│   │ falha    │   │          │   │              │        │ │
│  │  └──────────┘   └──────────┘   └──────────┘   └──────────────┘        │ │
│  │                                                                         │ │
│  │  • Persistência cross-session (SQLite)                                 │ │
│  │  • Exportável/Importável para compartilhar patterns                    │ │
│  │  • Previne repetição de erros conhecidos                               │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
│                                                                              │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │                          SISTEMA DE HOOKS                               │ │
│  │  • pre_evaluate: Antes de enviar para CLIs                             │ │
│  │  • post_evaluate: Após receber votos                                   │ │
│  │  • on_consensus: Quando consenso é alcançado                           │ │
│  │  • on_block: Quando avaliação é bloqueada                              │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
│                                                                              │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │                         SISTEMA DE PLUGINS                              │ │
│  │  • Novos executores (ex: Claude local, Llama, etc.)                    │ │
│  │  • Novos exportadores (JSON, CSV, Markdown)                            │ │
│  │  • Integrações (GitHub, GitLab, Jira)                                  │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
```

### 2.2 Fluxo de Dados com ReasoningBank

```
┌──────────┐    ┌──────────┐    ┌───────────┐    ┌──────────┐    ┌──────────┐
│  Claude  │    │ Reasoning│    │    3      │    │ Consenso │    │  Claude  │
│   Code   │───▶│   Bank   │───▶│   CLIs    │───▶│  Engine  │───▶│   Code   │
│  (input) │    │(RETRIEVE)│    │(parallel) │    │ (agreg)  │    │ (output) │
└──────────┘    └──────────┘    └───────────┘    └──────────┘    └──────────┘
     │                                                 │
     │                                                 ▼
     │                                        ┌──────────────┐
     │                                        │ ReasoningBank│
     │                                        │   (JUDGE +   │
     │                                        │   DISTILL +  │
     │                                        │ CONSOLIDATE) │
     │                                        └──────────────┘
     │                                                 │
     │              LOOP DE REFINAMENTO                │
     └─────────────────────────────────────────────────┘
```

---

## 3. ReasoningBank: Sistema de Aprendizado Contínuo

Inspirado no Claude-Flow, o ReasoningBank implementa um ciclo de aprendizado que melhora as avaliações ao longo do tempo.

### 3.1 O Ciclo RETRIEVE → JUDGE → DISTILL → CONSOLIDATE

```rust
// src/reasoning/bank.rs

use rusqlite::{Connection, params};
use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};

/// ReasoningBank - Sistema de aprendizado contínuo inspirado no Claude-Flow
pub struct ReasoningBank {
    conn: Connection,
    config: ReasoningConfig,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Pattern {
    pub id: i64,
    pub pattern_type: PatternType,
    pub code_signature: String,      // Hash ou fingerprint do código
    pub language: String,
    pub issue_category: String,      // "security", "logic", "performance", etc.
    pub description: String,
    pub solution: Option<String>,
    pub success_count: i32,          // Quantas vezes o pattern levou a sucesso
    pub failure_count: i32,          // Quantas vezes o pattern levou a falha
    pub confidence: f64,             // Calculado: success / (success + failure)
    pub last_seen: DateTime<Utc>,
    pub created_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PatternType {
    AntiPattern,    // Código que sempre falha
    GoodPattern,    // Código que sempre passa
    Ambiguous,      // Resultados mistos
}

impl ReasoningBank {
    /// Cria ou abre o banco de patterns
    pub fn new(db_path: &str) -> anyhow::Result<Self> {
        let conn = Connection::open(db_path)?;

        conn.execute_batch(r#"
            CREATE TABLE IF NOT EXISTS patterns (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                pattern_type TEXT NOT NULL,
                code_signature TEXT NOT NULL,
                language TEXT NOT NULL,
                issue_category TEXT NOT NULL,
                description TEXT NOT NULL,
                solution TEXT,
                success_count INTEGER DEFAULT 0,
                failure_count INTEGER DEFAULT 0,
                confidence REAL DEFAULT 0.5,
                last_seen TEXT NOT NULL,
                created_at TEXT NOT NULL,
                UNIQUE(code_signature, issue_category)
            );

            CREATE TABLE IF NOT EXISTS trajectories (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                pattern_id INTEGER REFERENCES patterns(id),
                request_id TEXT NOT NULL,
                code_hash TEXT NOT NULL,
                initial_score INTEGER,
                final_score INTEGER,
                loops_to_consensus INTEGER,
                was_successful BOOLEAN,
                timestamp TEXT NOT NULL
            );

            CREATE INDEX IF NOT EXISTS idx_patterns_signature ON patterns(code_signature);
            CREATE INDEX IF NOT EXISTS idx_patterns_category ON patterns(issue_category);
            CREATE INDEX IF NOT EXISTS idx_trajectories_pattern ON trajectories(pattern_id);
        "#)?;

        Ok(Self {
            conn,
            config: ReasoningConfig::default(),
        })
    }

    // ═══════════════════════════════════════════════════════════════════════
    // FASE 1: RETRIEVE - Busca patterns similares
    // ═══════════════════════════════════════════════════════════════════════

    /// Busca patterns conhecidos que podem afetar a avaliação
    pub fn retrieve(&self, code: &str, language: &str) -> Vec<PatternMatch> {
        let signature = self.compute_signature(code);
        let keywords = self.extract_keywords(code);

        let mut matches = Vec::new();

        // Busca por assinatura exata
        if let Ok(exact) = self.find_by_signature(&signature) {
            matches.extend(exact.into_iter().map(|p| PatternMatch {
                pattern: p,
                match_type: MatchType::Exact,
                relevance: 1.0,
            }));
        }

        // Busca por keywords (padrões conhecidos de problemas)
        for keyword in &keywords {
            if let Ok(keyword_matches) = self.find_by_keyword(keyword, language) {
                matches.extend(keyword_matches.into_iter().map(|p| PatternMatch {
                    relevance: 0.7, // Menos confiável que match exato
                    pattern: p,
                    match_type: MatchType::Keyword,
                }));
            }
        }

        // Ordena por relevância e confidence
        matches.sort_by(|a, b| {
            let score_a = a.relevance * a.pattern.confidence;
            let score_b = b.relevance * b.pattern.confidence;
            score_b.partial_cmp(&score_a).unwrap_or(std::cmp::Ordering::Equal)
        });

        // Retorna top N matches
        matches.truncate(self.config.max_patterns_per_query);
        matches
    }

    // ═══════════════════════════════════════════════════════════════════════
    // FASE 2: JUDGE - Avalia sucesso/falha da avaliação
    // ═══════════════════════════════════════════════════════════════════════

    /// Julga o resultado de uma avaliação e atualiza patterns
    pub fn judge(
        &mut self,
        request_id: &str,
        code: &str,
        language: &str,
        result: &EvaluationResult,
        loops_to_consensus: u32,
    ) -> anyhow::Result<JudgmentResult> {
        let signature = self.compute_signature(code);
        let was_successful = result.consensus_achieved && loops_to_consensus <= 2;

        // Registra trajetória
        let trajectory = Trajectory {
            request_id: request_id.to_string(),
            code_hash: signature.clone(),
            initial_score: result.votes.values().map(|v| v.score).min().unwrap_or(0),
            final_score: result.score,
            loops_to_consensus,
            was_successful,
            timestamp: Utc::now(),
        };

        // Para cada issue encontrado, atualiza ou cria pattern
        for finding in &result.findings {
            self.update_or_create_pattern(
                &signature,
                language,
                &finding.issue,
                finding.suggestion.as_deref(),
                &finding.severity,
                was_successful,
            )?;
        }

        // Se não houve issues e foi sucesso, registra como GoodPattern
        if result.findings.is_empty() && was_successful {
            self.register_good_pattern(&signature, language)?;
        }

        self.save_trajectory(&trajectory)?;

        Ok(JudgmentResult {
            was_successful,
            patterns_updated: result.findings.len(),
            new_patterns_created: 0, // Será atualizado pelo método
        })
    }

    // ═══════════════════════════════════════════════════════════════════════
    // FASE 3: DISTILL - Extrai learnings dos patterns
    // ═══════════════════════════════════════════════════════════════════════

    /// Destila conhecimento dos patterns para gerar insights
    pub fn distill(&self) -> DistilledKnowledge {
        // Top anti-patterns (mais falhas)
        let top_antipatterns = self.get_top_patterns(PatternType::AntiPattern, 10);

        // Top good patterns (mais sucessos)
        let top_good_patterns = self.get_top_patterns(PatternType::GoodPattern, 10);

        // Categorias mais problemáticas
        let problematic_categories = self.get_problematic_categories();

        // Linguagens com mais issues
        let language_stats = self.get_language_stats();

        // Tempo médio para consenso
        let avg_loops = self.get_average_loops_to_consensus();

        DistilledKnowledge {
            top_antipatterns,
            top_good_patterns,
            problematic_categories,
            language_stats,
            avg_loops_to_consensus: avg_loops,
            total_patterns: self.count_patterns(),
            total_trajectories: self.count_trajectories(),
        }
    }

    // ═══════════════════════════════════════════════════════════════════════
    // FASE 4: CONSOLIDATE - Previne esquecimento de patterns importantes
    // ═══════════════════════════════════════════════════════════════════════

    /// Consolida conhecimento, prevenindo esquecimento de patterns importantes
    pub fn consolidate(&mut self) -> anyhow::Result<ConsolidationResult> {
        let mut merged = 0;
        let mut pruned = 0;
        let mut reinforced = 0;

        // Merge patterns similares
        merged += self.merge_similar_patterns()?;

        // Remove patterns com baixa confiança e pouco uso
        pruned += self.prune_low_quality_patterns()?;

        // Reforça patterns que consistentemente previnem erros
        reinforced += self.reinforce_high_value_patterns()?;

        // Atualiza confidence de todos os patterns
        self.recalculate_all_confidences()?;

        Ok(ConsolidationResult {
            patterns_merged: merged,
            patterns_pruned: pruned,
            patterns_reinforced: reinforced,
        })
    }

    // ═══════════════════════════════════════════════════════════════════════
    // Métodos auxiliares
    // ═══════════════════════════════════════════════════════════════════════

    fn compute_signature(&self, code: &str) -> String {
        use sha2::{Sha256, Digest};

        // Normaliza código (remove whitespace extra, comentários)
        let normalized = self.normalize_code(code);

        let mut hasher = Sha256::new();
        hasher.update(normalized.as_bytes());
        hex::encode(hasher.finalize())
    }

    fn normalize_code(&self, code: &str) -> String {
        code.lines()
            .map(|l| l.trim())
            .filter(|l| !l.starts_with("//") && !l.starts_with("#") && !l.is_empty())
            .collect::<Vec<_>>()
            .join("\n")
    }

    fn extract_keywords(&self, code: &str) -> Vec<String> {
        // Extrai keywords que indicam patterns conhecidos
        let mut keywords = Vec::new();
        let code_lower = code.to_lowercase();

        // Keywords de segurança
        if code_lower.contains("sql") || code_lower.contains("query") {
            keywords.push("sql".to_string());
        }
        if code_lower.contains("password") || code_lower.contains("secret") {
            keywords.push("credentials".to_string());
        }
        if code_lower.contains("eval") || code_lower.contains("exec") {
            keywords.push("code_execution".to_string());
        }

        // Keywords de lógica
        if code_lower.contains("for") || code_lower.contains("while") {
            keywords.push("loop".to_string());
        }
        if code_lower.contains("unwrap") || code_lower.contains(".get(") {
            keywords.push("null_access".to_string());
        }

        keywords
    }

    /// Exporta ReasoningBank para compartilhar com outros
    pub fn export(&self, path: &str) -> anyhow::Result<()> {
        let knowledge = self.distill();
        let patterns = self.get_all_patterns()?;

        let export = ReasoningBankExport {
            version: "2.0".to_string(),
            exported_at: Utc::now(),
            knowledge,
            patterns,
        };

        let json = serde_json::to_string_pretty(&export)?;
        std::fs::write(path, json)?;

        Ok(())
    }

    /// Importa patterns de outro ReasoningBank
    pub fn import(&mut self, path: &str) -> anyhow::Result<ImportResult> {
        let json = std::fs::read_to_string(path)?;
        let export: ReasoningBankExport = serde_json::from_str(&json)?;

        let mut imported = 0;
        let mut skipped = 0;

        for pattern in export.patterns {
            if self.pattern_exists(&pattern.code_signature, &pattern.issue_category)? {
                // Merge com pattern existente
                self.merge_imported_pattern(&pattern)?;
                skipped += 1;
            } else {
                // Importa novo pattern
                self.insert_pattern(&pattern)?;
                imported += 1;
            }
        }

        Ok(ImportResult { imported, skipped })
    }
}
```

### 3.2 Integração com Avaliações

```rust
// src/mcp/server.rs (atualizado)

impl TetradServer {
    pub async fn evaluate(&self, request: EvaluationRequest) -> Result<EvaluationResult, ServerError> {
        let start = std::time::Instant::now();

        // ═══════════════════════════════════════════════════════════════════
        // FASE RETRIEVE: Busca patterns conhecidos
        // ═══════════════════════════════════════════════════════════════════
        let known_patterns = {
            let bank = self.reasoning_bank.read().await;
            bank.retrieve(&request.code, &request.language)
        };

        // Se há anti-patterns conhecidos, adiciona ao contexto
        let enriched_context = self.enrich_context_with_patterns(&request, &known_patterns);

        // Executa hooks pre_evaluate
        self.hooks.run_pre_evaluate(&request).await?;

        // ═══════════════════════════════════════════════════════════════════
        // Avaliação paralela nos 3 modelos
        // ═══════════════════════════════════════════════════════════════════
        let (codex_result, gemini_result, qwen_result) = tokio::join!(
            self.execute_with_fallback(&*self.codex, &request, &enriched_context),
            self.execute_with_fallback(&*self.gemini, &request, &enriched_context),
            self.execute_with_fallback(&*self.qwen, &request, &enriched_context)
        );

        // Coleta votos
        let votes = self.collect_votes(codex_result, gemini_result, qwen_result)?;

        // Calcula consenso
        let result = self.consensus.aggregate(&votes, &request);

        // Executa hooks post_evaluate
        self.hooks.run_post_evaluate(&request, &result).await?;

        // ═══════════════════════════════════════════════════════════════════
        // FASES JUDGE + DISTILL + CONSOLIDATE
        // ═══════════════════════════════════════════════════════════════════
        {
            let mut bank = self.reasoning_bank.write().await;

            // JUDGE: Registra resultado
            bank.judge(
                &request.request_id,
                &request.code,
                &request.language,
                &result,
                self.current_loop_count,
            )?;

            // CONSOLIDATE: Periodicamente (a cada N avaliações)
            if self.evaluation_count % self.config.consolidation_interval == 0 {
                bank.consolidate()?;
            }
        }

        // Hooks de consenso/bloqueio
        if result.consensus_achieved {
            self.hooks.run_on_consensus(&result).await?;
        } else if result.decision == Decision::Block {
            self.hooks.run_on_block(&result).await?;
        }

        // Métricas
        let duration = start.elapsed();
        tracing::info!(
            request_id = %request.request_id,
            decision = ?result.decision,
            score = result.score,
            patterns_matched = known_patterns.len(),
            duration_ms = duration.as_millis(),
            "evaluation_completed"
        );

        Ok(result)
    }

    fn enrich_context_with_patterns(
        &self,
        request: &EvaluationRequest,
        patterns: &[PatternMatch],
    ) -> String {
        let mut context = request.context.clone().unwrap_or_default();

        if !patterns.is_empty() {
            context.push_str("\n\n## Patterns Conhecidos do ReasoningBank\n");
            context.push_str("O código apresenta características similares a patterns conhecidos:\n\n");

            for (i, pm) in patterns.iter().take(5).enumerate() {
                context.push_str(&format!(
                    "{}. **{}** (confidence: {:.0}%)\n   - {}\n",
                    i + 1,
                    pm.pattern.issue_category,
                    pm.pattern.confidence * 100.0,
                    pm.pattern.description
                ));

                if let Some(solution) = &pm.pattern.solution {
                    context.push_str(&format!("   - Solução sugerida: {}\n", solution));
                }
            }

            context.push_str("\nPor favor, verifique especialmente esses aspectos.\n");
        }

        context
    }
}
```

---

## 4. Sistema de Hooks

Inspirado nos 17 hooks do Claude-Flow, o Tetrad oferece um sistema de callbacks para customização.

```rust
// src/hooks/mod.rs

use async_trait::async_trait;

#[async_trait]
pub trait Hook: Send + Sync {
    fn name(&self) -> &str;
    async fn execute(&self, context: &HookContext) -> anyhow::Result<HookResult>;
}

pub struct HookSystem {
    pre_evaluate: Vec<Box<dyn Hook>>,
    post_evaluate: Vec<Box<dyn Hook>>,
    on_consensus: Vec<Box<dyn Hook>>,
    on_block: Vec<Box<dyn Hook>>,
}

impl HookSystem {
    pub fn new() -> Self {
        Self {
            pre_evaluate: Vec::new(),
            post_evaluate: Vec::new(),
            on_consensus: Vec::new(),
            on_block: Vec::new(),
        }
    }

    pub fn register(&mut self, event: HookEvent, hook: Box<dyn Hook>) {
        match event {
            HookEvent::PreEvaluate => self.pre_evaluate.push(hook),
            HookEvent::PostEvaluate => self.post_evaluate.push(hook),
            HookEvent::OnConsensus => self.on_consensus.push(hook),
            HookEvent::OnBlock => self.on_block.push(hook),
        }
    }

    pub async fn run_pre_evaluate(&self, request: &EvaluationRequest) -> anyhow::Result<()> {
        let context = HookContext::PreEvaluate { request };
        for hook in &self.pre_evaluate {
            hook.execute(&context).await?;
        }
        Ok(())
    }

    // ... outros métodos run_*
}

// Exemplo de hook customizado
pub struct LoggingHook;

#[async_trait]
impl Hook for LoggingHook {
    fn name(&self) -> &str {
        "logging"
    }

    async fn execute(&self, context: &HookContext) -> anyhow::Result<HookResult> {
        match context {
            HookContext::PreEvaluate { request } => {
                tracing::info!(request_id = %request.request_id, "Starting evaluation");
            }
            HookContext::PostEvaluate { result, .. } => {
                tracing::info!(
                    decision = ?result.decision,
                    score = result.score,
                    "Evaluation completed"
                );
            }
            _ => {}
        }
        Ok(HookResult::Continue)
    }
}
```

---

## 5. Sistema de Plugins

Para permitir extensibilidade como o Claude-Flow.

```rust
// src/plugins/mod.rs

use async_trait::async_trait;

/// Trait para novos executores de avaliação
#[async_trait]
pub trait ExecutorPlugin: Send + Sync {
    fn name(&self) -> &str;
    fn version(&self) -> &str;
    async fn evaluate(&self, request: &EvaluationRequest) -> Result<ModelVote, PluginError>;
    fn specialization(&self) -> &str; // "syntax", "architecture", "logic", etc.
}

/// Trait para exportadores de resultados
pub trait ExporterPlugin: Send + Sync {
    fn name(&self) -> &str;
    fn export(&self, results: &[EvaluationResult], path: &str) -> anyhow::Result<()>;
}

/// Gerenciador de plugins
pub struct PluginManager {
    executors: Vec<Box<dyn ExecutorPlugin>>,
    exporters: Vec<Box<dyn ExporterPlugin>>,
}

impl PluginManager {
    pub fn new() -> Self {
        Self {
            executors: Vec::new(),
            exporters: Vec::new(),
        }
    }

    pub fn load_from_directory(&mut self, path: &str) -> anyhow::Result<()> {
        // Carrega plugins de arquivos .so/.dylib/.dll
        // Ou de arquivos WASM para plugins sandboxed
        todo!("Plugin loading")
    }

    pub fn register_executor(&mut self, executor: Box<dyn ExecutorPlugin>) {
        tracing::info!(
            name = executor.name(),
            version = executor.version(),
            "Registered executor plugin"
        );
        self.executors.push(executor);
    }
}
```

---

## 6. CLAUDE.md - Documentação para Claude Code

Crie este arquivo no seu projeto para que o Claude Code saiba usar o Tetrad automaticamente.

```markdown
# Tetrad Integration

Este projeto usa **Tetrad** para validação de código por consenso quádruplo.

## Configuração

Tetrad está configurado como MCP server. As ferramentas disponíveis são:

### Ferramentas Obrigatórias

Você DEVE usar estas ferramentas antes de salvar código:

1. **`tetrad_review_plan`** - Use ANTES de começar a implementar
2. **`tetrad_review_code`** - Use ANTES de salvar qualquer arquivo
3. **`tetrad_review_tests`** - Use ANTES de finalizar testes
4. **`tetrad_confirm`** - Use para confirmar que concorda com feedback
5. **`tetrad_final_check`** - Use após todas as correções

### Fluxo de Trabalho

```
1. Gerar plano → tetrad_review_plan
2. Se REVISE: ajustar plano → tetrad_confirm → retry
3. Implementar → tetrad_review_code
4. Se REVISE: corrigir → tetrad_confirm → retry
5. Testes → tetrad_review_tests
6. tetrad_final_check → CERTIFIED
```

### Regras

- NUNCA salve código sem passar por tetrad_review_code
- Se receber BLOCK, pare e corrija TODOS os issues críticos
- Se 2+ modelos apontam o mesmo problema, é consenso forte - corrija
- Qwen foca em bugs lógicos - preste atenção especial
- Gemini foca em arquitetura - verifique impacto em outros módulos
- Codex foca em sintaxe - siga as convenções

### ReasoningBank

O Tetrad aprende com avaliações passadas. Se você receber um aviso sobre
"pattern conhecido", significa que código similar já causou problemas antes.
Preste atenção especial a esses avisos.
```

---

## 7. Estrutura do Projeto (Atualizada)

```
tetrad/
├── Cargo.toml                    # Manifesto do crate
├── Cargo.lock
├── README.md                     # Documentação para usuários
├── CLAUDE.md                     # Documentação para Claude Code
├── LICENSE                       # MIT
├── src/
│   ├── main.rs                   # Entry point (CLI)
│   ├── lib.rs                    # Biblioteca exportável
│   ├── cli/
│   │   ├── mod.rs
│   │   ├── commands.rs           # Comandos CLI (init, serve, status, etc.)
│   │   └── interactive.rs        # Configuração interativa
│   ├── mcp/
│   │   ├── mod.rs
│   │   ├── server.rs             # MCP server implementation
│   │   ├── protocol.rs           # MCP protocol types
│   │   ├── tools.rs              # Tool handlers
│   │   └── transport.rs          # stdio, HTTP transports
│   ├── executors/
│   │   ├── mod.rs
│   │   ├── base.rs               # Trait CliExecutor
│   │   ├── codex.rs              # Codex CLI wrapper
│   │   ├── gemini.rs             # Gemini CLI wrapper
│   │   └── qwen.rs               # Qwen CLI wrapper
│   ├── consensus/
│   │   ├── mod.rs
│   │   ├── engine.rs             # Motor de consenso
│   │   ├── rules.rs              # Regras de decisão
│   │   └── aggregator.rs         # Agregação de votos
│   ├── reasoning/
│   │   ├── mod.rs
│   │   ├── bank.rs               # ReasoningBank (SQLite)
│   │   ├── patterns.rs           # Pattern matching
│   │   └── export.rs             # Export/Import
│   ├── hooks/
│   │   ├── mod.rs
│   │   └── builtin.rs            # Hooks padrão
│   ├── plugins/
│   │   ├── mod.rs
│   │   └── loader.rs             # Carregador de plugins
│   ├── prompts/
│   │   ├── mod.rs
│   │   ├── templates.rs          # Templates de prompts
│   │   └── builders.rs           # Builders de prompts
│   ├── cache/
│   │   ├── mod.rs
│   │   └── lru.rs                # LRU cache
│   └── types/
│       ├── mod.rs
│       ├── requests.rs           # Tipos de request
│       ├── responses.rs          # Tipos de response
│       ├── config.rs             # Configuração
│       └── errors.rs             # Error types
├── tests/
│   ├── integration/
│   │   ├── test_cli.rs
│   │   ├── test_mcp.rs
│   │   ├── test_reasoning.rs
│   │   └── test_consensus.rs
│   └── fixtures/
│       ├── good_code/
│       ├── bad_code/
│       └── patterns/
├── config/
│   └── default.toml              # Configuração padrão
├── plugins/                      # Plugins de exemplo
│   └── example_executor/
└── .github/
    └── workflows/
        ├── ci.yml                # CI/CD
        └── release.yml           # Release para crates.io
```

---

## 8. Cargo.toml (Atualizado para Distribuição)

```toml
[package]
name = "tetrad"
version = "2.0.0"
edition = "2024"
authors = ["SamoraDC <samora@example.com>"]
description = "MCP de Consenso Quádruplo para Claude Code - Valida código usando Codex, Gemini e Qwen"
license = "MIT"
repository = "https://github.com/seu-usuario/tetrad"
homepage = "https://github.com/seu-usuario/tetrad"
documentation = "https://docs.rs/tetrad"
readme = "README.md"
keywords = ["mcp", "claude", "code-review", "ai", "consensus"]
categories = ["development-tools", "command-line-utilities"]

[lib]
name = "tetrad"
path = "src/lib.rs"

[[bin]]
name = "tetrad"
path = "src/main.rs"

[features]
default = ["cli", "sqlite"]
cli = ["clap", "dialoguer", "indicatif"]
sqlite = ["rusqlite"]
postgres = ["sqlx"]  # Para enterprise
plugins = ["libloading"]

[dependencies]
# Async runtime
tokio = { version = "1.45", features = ["full"] }
async-trait = "0.1"

# Serialization
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

# MCP Protocol
# Nota: usar implementação própria ou crate da comunidade

# CLI
clap = { version = "4.5", features = ["derive"], optional = true }
dialoguer = { version = "0.11", optional = true }
indicatif = { version = "0.17", optional = true }

# Database
rusqlite = { version = "0.32", features = ["bundled"], optional = true }
sqlx = { version = "0.8", features = ["runtime-tokio", "postgres"], optional = true }

# CLI execution
tokio-process = "0.2"

# Caching
lru = "0.12"

# Hashing
sha2 = "0.10"
hex = "0.4"

# Configuration
config = "0.14"
toml = "0.8"

# Logging
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["json", "env-filter"] }

# Error handling
thiserror = "2.0"
anyhow = "1.0"

# Utilities
uuid = { version = "1.11", features = ["v4"] }
chrono = { version = "0.4", features = ["serde"] }
regex = "1.11"

# Plugins (opcional)
libloading = { version = "0.8", optional = true }

[dev-dependencies]
tokio-test = "0.4"
mockall = "0.13"
tempfile = "3.14"
assert_cmd = "2.0"
predicates = "3.1"

[profile.release]
lto = true
codegen-units = 1
strip = true

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
```

---

## 9. Publicação e Distribuição

### 9.1 Publicar no crates.io

```bash
# Login no crates.io
cargo login

# Verificar antes de publicar
cargo publish --dry-run

# Publicar
cargo publish
```

### 9.2 GitHub Releases com Binários

```yaml
# .github/workflows/release.yml
name: Release

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    strategy:
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
          - target: x86_64-apple-darwin
            os: macos-latest
          - target: aarch64-apple-darwin
            os: macos-latest
          - target: x86_64-pc-windows-msvc
            os: windows-latest

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - name: Build
        run: cargo build --release --target ${{ matrix.target }}

      - name: Package
        shell: bash
        run: |
          cd target/${{ matrix.target }}/release
          if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
            7z a ../../../tetrad-${{ matrix.target }}.zip tetrad.exe
          else
            tar czf ../../../tetrad-${{ matrix.target }}.tar.gz tetrad
          fi

      - name: Upload
        uses: softprops/action-gh-release@v1
        with:
          files: tetrad-*
```

### 9.3 Homebrew Formula

```ruby
# Formula/tetrad.rb
class Tetrad < Formula
  desc "MCP de Consenso Quádruplo para Claude Code"
  homepage "https://github.com/seu-usuario/tetrad"
  url "https://github.com/seu-usuario/tetrad/releases/download/v2.0.0/tetrad-x86_64-apple-darwin.tar.gz"
  sha256 "..."
  license "MIT"

  def install
    bin.install "tetrad"
  end

  test do
    assert_match "tetrad", shell_output("#{bin}/tetrad --version")
  end
end
```

---

## 10. Configuração no Claude Code

### 10.1 Adição Automática (Recomendado)

```bash
# Similar ao Claude-Flow
claude mcp add tetrad -- tetrad serve
```

### 10.2 Manual em ~/.claude/settings.json

```json
{
  "mcpServers": {
    "tetrad": {
      "command": "tetrad",
      "args": ["serve"],
      "env": {
        "GEMINI_API_KEY": "${GEMINI_API_KEY}",
        "OPENAI_API_KEY": "${OPENAI_API_KEY}",
        "TETRAD_LOG_LEVEL": "info"
      }
    }
  }
}
```

---

## 11. Comparação com Claude-Flow

| Feature | Claude-Flow | Tetrad |
|---------|-------------|--------|
| **Linguagem** | TypeScript | Rust |
| **Foco** | Orquestração de agentes | Validação de código |
| **Aprendizado** | ReasoningBank (RuVector) | ReasoningBank (SQLite) |
| **Modelos** | Claude/GPT/Gemini/Ollama | Codex CLI/Gemini CLI/Qwen CLI |
| **Agentes** | 54+ agentes | 3 avaliadores especializados |
| **Consenso** | Raft/Byzantine/Gossip | Regra de Ouro/Fraco/Forte |
| **Instalação** | npm install | cargo install |
| **MCP Tools** | 175+ | 6 focadas |
| **Uso de memória** | Médio (Node.js) | Baixo (Rust) |
| **Latência** | ~100ms | ~50ms |

### Uso Conjunto

Tetrad e Claude-Flow podem trabalhar juntos:

```yaml
# claude-flow workflow que usa Tetrad
name: validated_swarm
triggers:
  - on_code_generated

steps:
  - name: validate_with_tetrad
    tool: tetrad_review_code
    on_block: abort_swarm

  - name: continue_swarm
    when: "{{ tetrad_result.consensus_achieved }}"
    action: proceed
```

---

## 12. Roadmap de Implementação (Atualizado)

### Fase 1: Fundação (Semana 1) ✅ COMPLETA
- [x] Setup projeto Rust com estrutura de crate publicável
- [x] CLI básico com clap (init, serve, status, config, doctor, version)
- [x] Implementar trait CliExecutor
- [x] Testes unitários básicos (12 testes passando)
- [x] CodexExecutor, GeminiExecutor, QwenExecutor implementados
- [x] Health checks com `is_available()` e `version()`
- [x] Parsing robusto de JSON com `ExecutorResponse::parse_from_output()`

### Fase 2: Executores (Semana 2) ✅ COMPLETA (incluída na Fase 1)
- [x] CodexExecutor
- [x] GeminiExecutor
- [x] QwenExecutor
- [x] Health checks
- [x] Parsing robusto de JSON

### Fase 3: Consenso + ReasoningBank (Semana 3) ✅ COMPLETA
- [x] Motor de consenso (rules.rs, aggregator.rs, engine.rs)
- [x] ReasoningBank com SQLite (bank.rs)
- [x] Ciclo RETRIEVE→JUDGE→DISTILL→CONSOLIDATE
- [x] Export/Import de patterns (export.rs)
- [x] Pattern matching (patterns.rs)
- [x] CLI comandos: evaluate, history, export, import
- [x] 66 testes passando

### Fase 4: MCP Server (Semana 4) ✅ COMPLETA
- [x] Protocolo MCP (stdio) - JSON-RPC 2.0 com Content-Length headers
- [x] 6 ferramentas expostas (review_plan/code/tests, confirm, final_check, status)
- [x] Cache LRU com TTL para resultados de avaliação
- [x] Hooks básicos (pre/post_evaluate, on_consensus, on_block)
- [x] Sistema de confirmações integrado (confirm → final_check)
- [x] 126 testes passando

### Fase 5: Polish (Semana 5) ✅ COMPLETA
- [x] CLI interativo completo (dialoguer para config)
- [x] Documentação (README.md, CLAUDE.md, CHANGELOG.md)
- [x] Testes de integração (205 testes passando: 127 unitários + 78 integração)
- [x] GitHub Actions CI/CD (ci.yml, release.yml)
- [x] Correção de args dos executores (prompt posicional)
- [x] CacheConfig conectado ao sistema

### Fase 6: Release (Semana 6) 🔄 EM ANDAMENTO
- [ ] Publicar no crates.io
- [ ] GitHub Releases com binários
- [ ] Homebrew formula
- [ ] Anúncio

---

## 13. Conclusão

**Tetrad v2.0** combina o melhor dos planos anteriores com as inovações do Claude-Flow:

1. **Consenso quádruplo**: 4 modelos devem concordar
2. **ReasoningBank**: Aprende com cada avaliação (RETRIEVE→JUDGE→DISTILL→CONSOLIDATE)
3. **Distribuição fácil**: `cargo install tetrad`
4. **CLI completa**: Comandos intuitivos como Claude-Flow
5. **Extensível**: Sistema de hooks e plugins
6. **Cross-session**: Persistência com SQLite
7. **Compartilhável**: Export/Import de patterns aprendidos

O sistema está pronto para ser usado por qualquer desenvolvedor que queira **código validado por 4 inteligências** com **aprendizado contínuo**.
