Phase 20: Arquitetura de Bots Federados

Arc OS — de "um escritório" para "centro de comando para todos os projetos" Autor: Rick (Arquiteto Principal) | Data: 2026-04-02 Status: 20.1–20.5 COMPLETE Aprovado por: CEO


O Problema

O CEO gerencia múltiplos projetos (Arc OS, Msolution, RTS_001) pelo celular. Arquitetura atual: um bot Telegram → uma sessão Claude → uma janela de contexto. Isso quebra com 3+ projetos:

A Solução: Federação

CEO ↔ @citadel_master_bot (Master)          ← apenas comandos globais
       │
       ├── /status          → consulta todos os children
       ├── /emergency-stop  → sinal de kill para todos
       ├── /deploy all      → deploy em cascata
       │
       ├── @citadel_v2_bot (Child 1)         ← chat separado, contexto separado
       │    └── Sessão Claude #1, cwd=/opt/repos/citadel-v2
       │
       ├── @msolution_bot (Child 2)          ← pode adicionar designer ao chat
       │    └── Sessão Claude #2, cwd=/opt/repos/msol
       │
       └── @rts_bot (Child 3)               ← pode adicionar agente Morty
            └── Sessão Claude #3, cwd=/opt/repos/rts-001

Análise de Decisão: Bot Único vs Federação

Opção A: Bot Único + Seletor de Projeto

Critério Avaliação Detalhes
Complexidade de código Baixa (1 bot) Adiciona variável activeProject, /switch muda o cwd
Isolamento de contexto FRACO Uma sessão Claude = uma janela de contexto para todos os projetos. Trocar polui o contexto.
Conveniência do CEO Média Precisa lembrar de usar /switch. Risco: enviar tarefa para o projeto errado. Sem separação visual.
Multi-usuário IMPOSSÍVEL Um chat = um CEO. Não dá pra convidar pessoas para um chat com escopo de projeto.
Contexto de reply QUEBRADO Responder mensagem de outro projeto = Claude confuso.

Veredicto: Funciona para CEO solo com 1-2 projetos. Quebra com 3+.

Opção B: Bots Federados (Master + Children) — ESCOLHIDA

Critério Avaliação Detalhes
Complexidade de código Média (N+1 bots) Cada bot = tmux separado + sessão Claude. Master = coordenador leve.
Isolamento de contexto PERFEITO Cada sessão Claude = janela de contexto própria, CLAUDE.md próprio, cwd próprio. Zero poluição.
Conveniência do CEO ALTA Chats Telegram separados = "salas" separadas. Desliza entre projetos. UX mobile nativa.
Multi-usuário NATIVO Adiciona @designer ao chat do @msolution_bot. Ela vê apenas o projeto dela.
Contexto de reply PERFEITO Reply no chat do @citadel_v2_bot = 100% contexto citadel. O Telegram preserva o thread nativamente.

Veredicto: Solução correta. Mais complexidade de infra, mas resolve TODOS os problemas.

Por que a Federação Vence

  1. Isolamento de contexto — fator decisivo. Uma sessão Claude para 3+ projetos = overflow de contexto em 30 minutos de trabalho ativo. A federação dá a cada projeto 200K tokens limpos.
  2. Prontidão multi-usuário — não é "funcionalidade futura", é uma fundação. Sem isso, o Arc OS não pode se tornar um produto.
  3. Reply = RAG nativo — o Telegram já resolveu o problema de contexto. Apenas mapeamos reply → prompt GSD.

Arquitetura de Emergency Stop

CEO toca /emergency-stop no chat do Master
        │
        ▼
Master Bot (Node.js/Bun, leve, NÃO é uma sessão Claude)
        │
        ├── 1. Lê config/bot_registry.json
        │      { "children": [
        │          { "name": "citadel-v2", "tmux": "citadel", ... },
        │          { "name": "msolution", "tmux": "msolution", ... }
        │      ]}
        │
        ├── 2. Para cada child (em paralelo):
        │      a) tmux send-keys -t $SESSION "C-c" Enter      ← graceful: Ctrl+C
        │      b) sleep 2
        │      c) tmux send-keys -t $SESSION "/exit" Enter     ← saída explícita
        │      d) sleep 2
        │      e) tmux kill-session -t $SESSION                 ← força kill se ainda ativo
        │
        ├── 3. Atualiza office-state.json: todos os agentes → idle
        │
        └── 4. Responde no chat do Master:
               "EMERGENCY STOP executed.
                citadel-v2: STOPPED (was: working on hooks)
                msolution: STOPPED (was: idle)
                All agents reset to idle."

Protocolo de Kill (3 níveis)

Nível Ação Timeout Quando
1. Graceful Ctrl+C via tmux 2s Sempre primeiro
2. Explícito Comando /exit 2s Se o graceful não funcionou
3. Força tmux kill-session imediato Último recurso

Failsafe

Job cron a cada 5 minutos verifica /tmp/emergency-stop.flag. Se o arquivo existe e é recente (<10 min), executa a sequência de kill. Cobre o caso em que o próprio Master Bot crashou.


Smart Context Recall

Problema

O CEO responde a uma mensagem de 3 dias atrás e diz "faz o mesmo para outro módulo". O Claude não tem ideia da mensagem referenciada.

Solução: Transformação Reply → Prompt GSD

A Telegram Bot API fornece o objeto reply_to_message com o texto original completo.

CEO responde a: "I deployed hooks to VPS, everything works"
CEO escreve: "do the same for msolution"
        │
        ▼
Child Bot recebe:
{
  "message": {
    "text": "do the same for msolution",
    "reply_to_message": {
      "text": "I deployed hooks to VPS, everything works",
      "date": 1743580800,
      "message_id": 847
    }
  }
}
        │
        ▼
Bot constrói prompt GSD para Claude:
┌─────────────────────────────────────┐
│ CONTEXT (from reply):               │
│ > [2026-04-02] "I deployed hooks    │
│ > to VPS, everything works"         │
│                                     │
│ TASK (new message):                 │
│ "do the same for msolution"         │
│                                     │
│ PROJECT: msolution (from bot scope) │
└─────────────────────────────────────┘

Deep Recall (mensagens mais antigas)

Camada 1: Histórico do Thread (rápido)
  Bot armazena as últimas 50 mensagens em state/thread_history.json por chat.
  Reply → bot encontra o original → injeta no bloco CONTEXT.

Camada 2: Library Recall (fallback)
  Se mensagem não está no histórico do thread (>50 mensagens atrás) →
  bot executa /citadel-recall com texto do reply →
  puxa contexto de library-export/ → injeta no prompt.

Fluxo: reply_to_message → thread_history → library-export/ → prompt GSD

Princípio-Chave

O Claude NUNCA sabe sobre os replies do Telegram diretamente. O middleware do bot SEMPRE transforma o reply em um bloco limpo CONTEXT + TASK antes de enviar para a sessão Claude.


Especificação do Master Bot

O que o Master Bot É

O que o Master Bot NÃO É

Protocolo do Child Bot

Cada child bot deve:

  1. Registrar em config/bot_registry.json na inicialização
  2. Enviar heartbeat (a cada 60s) ao Master via arquivo: state/heartbeat_<name>.json
  3. Tratar reply_to_message → injeção de CONTEXT no GSD
  4. Armazenar as últimas 50 mensagens em state/thread_history.json
  5. Responder ao sinal de emergency-stop (Ctrl+C graceful → /exit → kill)
  6. Usar logger estruturado (shared/logger.ts) — logs em /var/log/citadel/<name>/
  7. Aceitar variável de ambiente BOT_NAME para nomeação dinâmica
  8. Expor /api/child/health para health checks do watchdog

Estimativa de Recursos

Recurso Atual Phase 20
RAM do VPS ~4GB usados / 11GB total ~5,5GB (+ ~500MB por sessão child)
Containers Docker 2 (bridge + frontend) 4-5 (+ master + 2 children)
Tokens de bot Telegram 1 3-4 (@BotFather, gratuito)
Sessões tmux 1 (citadel) 3-4 (master + children)
Portas 18889, 19200 + 19201-19203 (APIs dos children)

Sub-Phases da Phase 20

20.1 — Fundação do Master Bot

20.2 — Protocolo do Child Bot (Primeiro Child)

20.3 — Motor de Onboarding (DONE)

20.4 — Biblioteca de Skills e Remoção de Projeto (DONE)

20.5 — Infraestrutura Phantom-Ready (DONE)

Comandos do Master Bot (Final)

Comando Ação Resposta
/status Lê estado + health + heartbeat de todos os children dashboard agregado
/emergency_stop Sequência de kill de 3 níveis em todos os children Confirmação com status por child
/list Mostra children registrados Nome, status, sessão tmux
/deploy <name|all> Aciona deploy para o(s) child(ren) Log de deploy por child
/health Verifica endpoints de health de todos os children Matriz de health
/new_project <name> Inicia entrevista de onboarding Conversa em 4 etapas
/remove_project <name> Remove projeto com confirmação Tripla confirmação + limpeza
/watchdog Mostra status do watchdog Falhas, restarts, backoff por child
/cancel Cancela operação ativa Aborta onboarding/remoção

Fora do Escopo (Phase 21+)


Arquitetura da Phase 20 por Rick (Arquiteto Principal). Phases 20.1–20.5 completas. Aprovado pelo CEO em 2026-04-02.