--- name: clip-health description: Diagnóstico rápido Paperclip — serviço, BD, heartbeats falhados, budget, disco. Usar quando "clip health", "saúde clip", "diagnóstico paperclip", "clip problemas". context: fork layer: wiki --- # /clip-health — Diagnostico Paperclip Verificacao rapida da saude do sistema Clip. ## Constantes ``` BD: PGPASSWORD="paperclip" psql -h localhost -p 54329 -U paperclip -d paperclip PAPERCLIP_DIR: /home/ealmeida/paperclip INSTANCE_DIR: /home/ealmeida/.paperclip/instances/default ``` ## Procedimento Executar todas as verificacoes em paralelo, depois apresentar relatorio. ### Check 1: Serviço ```bash ps aux | grep -E "paperclip.*src/index|pnpm.*paperclipai" | grep -v grep | head -5 ``` - Processos encontrados = OK - Nenhum processo = CRITICO (iniciar com: `cd /home/ealmeida/paperclip && pnpm --filter @paperclipai/server dev`) Verificar também memória partilhada PostgreSQL (causa do bug POSIX shared memory): ```bash ls /dev/shm/PostgreSQL.* 2>/dev/null && echo "POSIX OK" || echo "POSIX em falta — BD pode falhar ao ligar" ``` - POSIX OK = OK - POSIX em falta + processos activos = AVISO (PostgreSQL perdeu shared memory — reiniciar Paperclip) - POSIX em falta + sem processos = CRITICO ### Check 2: Base de dados Conexao: ```sql SELECT 1 as connected; ``` Tamanho: ```sql SELECT pg_size_pretty(pg_database_size('paperclip')) as db_size; ``` Contagens: ```sql SELECT (SELECT COUNT(*) FROM agents WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f') as agentes, (SELECT COUNT(*) FROM issues WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f') as issues, (SELECT COUNT(*) FROM heartbeat_runs hr JOIN agents a ON hr.agent_id = a.id WHERE a.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f') as heartbeats; ``` - Conexao OK = OK - Conexao falha = CRITICO ### Check 3: Heartbeats falhados (24h) ```sql SELECT a.name, hr.status, LEFT(hr.error, 70) as erro, hr.started_at::timestamp(0) FROM heartbeat_runs hr JOIN agents a ON hr.agent_id = a.id WHERE a.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f' AND hr.status IN ('failed','error') AND hr.started_at > NOW() - INTERVAL '24 hours' ORDER BY hr.started_at DESC LIMIT 20; ``` - 0 falhas = OK - 1-2 falhas = AVISO - 3+ falhas = CRITICO ### Check 4: Budget ```sql SELECT name, budget_monthly_cents, spent_monthly_cents, CASE WHEN budget_monthly_cents > 0 THEN ROUND(spent_monthly_cents::numeric / budget_monthly_cents * 100, 1) ELSE 0 END as pct FROM agents WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f' AND budget_monthly_cents > 0 AND spent_monthly_cents > 0 ORDER BY pct DESC; ``` - <80% = OK - 80-95% = AVISO - >95% = CRITICO ### Check 5: Disco ```bash df -h /home/ealmeida/.paperclip/ | tail -1 ``` ```bash du -sh /home/ealmeida/.paperclip/instances/default/db/ 2>/dev/null du -sh /home/ealmeida/.paperclip/instances/default/logs/ 2>/dev/null du -sh /home/ealmeida/.paperclip/instances/default/data/ 2>/dev/null ``` - >30% livre = OK - 15-30% livre = AVISO - <15% livre = CRITICO ### Check 6: API Health ```bash curl -s --max-time 5 http://localhost:3100/health 2>/dev/null || echo "FALHA" ``` Esperado: `{"status":"ok","version":"...","deploymentMode":"authenticated","bootstrapStatus":"ready"}` - `status: ok` = OK - `{"error":"Board access required"}` = AVISO (API responde mas sem auth — BD operacional) - FALHA/timeout = CRITICO (servidor não responde) ### Check 7: Gateway MCPs ```bash curl -s --max-time 5 https://gateway.descomplicar.pt/health 2>/dev/null || echo "FALHA" ``` - Responde = OK - Timeout/falha = AVISO ### Check 8: Referencias orfas na BD Budget policies e incidents a referenciar entidades inexistentes: Invocar tool MCP: `mcp__paperclip__diag_budget_orphans` - 0 orfaos = OK - 1+ orfaos = CRITICO (causa "Agent not found" no dashboard, apagar com DELETE) ### Check 9: Instancias duplicadas ```bash ss -tlnp | grep -E "310[0-9]" | wc -l ``` - 1 instancia = OK - 2+ instancias = CRITICO (processos orfaos do pnpm, matar com `kill -9` os PIDs com PPID=1) Detalhe dos processos: ```bash ss -tlnp | grep -E "310[0-9]" ``` ### Check 10: Porta vs Cloudflare Tunnel ```bash TUNNEL_PORT=$(grep -A1 "clip.descomplicar.pt" ~/.cloudflared/config.yml | grep service | grep -oP ':\K[0-9]+') ACTUAL_PORT=$(ss -tlnp | grep -E "310[0-9]" | head -1 | grep -oP ':310[0-9]' | tr -d ':') echo "Tunnel: $TUNNEL_PORT | Servidor: $ACTUAL_PORT" ``` - Iguais = OK - Diferentes = CRITICO (tunnel a apontar para porta errada, dashboard inacessivel) ### Check 11: Agentes sem permissoes bash Invocar tool MCP: `mcp__paperclip__diag_agents_without_skip_permissions` - 0 = OK - 1+ = CRITICO (agentes vao ficar bloqueados ao executar bash — corrigir com `/clip-agent`) ### Check 12: Agentes sem heartbeat Invocar tool MCP: `mcp__paperclip__diag_agents_missing_heartbeat` - 0 = OK - 1+ = AVISO (agentes nao acordam — podem nao processar issues) ### Check 13: Routine triggers com kind errado ou next_run_at NULL Invocar tool MCP: `mcp__pap