# Plano mestre da conversa de origem Fonte: tarefa **Planejar nova VPS de odds**, ID `01a036ea-0842-7410-a003-3226907b9f3e`, plano estruturado `01a036ea-0b11-7903-9647-6b71d6513c0b-plan`. Este documento preserva integralmente o plano original como referência histórica. Decisões posteriores da conversa adotaram PostgreSQL desde o início e ampliaram o console. Nesta tarefa, o dono definiu teste paralelo de 10–20 casas, prioridades existentes e armazenamento local seletivo. Para executar, consultar a reconciliação e as tarefas em `progresso/plano_execucao.json`; não tratar parâmetros históricos como operação já aprovada ou comprovada. --- # Plano mestre — VPSNOVA: serviço de odds pré-live e assistente operacional Hermes ## 1. Objetivo, limites e fontes de verdade A nova VPS será um nó único inicialmente, preparado para expansão, responsável por: - Capturar e organizar odds pré-live de futebol. - Suportar as 24 fontes do catálogo, ativando-as gradualmente por prontidão técnica. - Entregar odds canônicas a um painel hospedado em outro servidor. - Fornecer REST para carga/recuperação e SSE para atualizações contínuas. - Hospedar Hermes como assistente dessa perna, com Telegram, dashboard web e autonomia limitada. - Manter Grafana como painel operacional. - Desenvolver em paralelo memória compartilhada com OpenViking, sem colocá-la no caminho crítico das odds. Ficam fora da primeira entrega: - Arbitragem, EV ou decisões de aposta. - Alterações no painel externo. - Compatibilidade com a API antiga. - Usuários finais conversando com LLM. - Obrigação de colocar as 24 fontes online simultaneamente. - AdsPower. A referência conceitual do contrato será [USOS_V2_PROPOSTA.md](), corrigindo as ambiguidades identificadas na revisão. O corpus bruto do `PACIFICADORPROP` será evidência e conjunto golden; o harmonizador antigo não será promovido a runtime. ## 2. Gate 0 — segurança e preparação obrigatória Antes de instalar aplicações: 1. **Rotacionar credenciais expostas** - Revogar o token Hostinger enviado no chat. - Rotacionar a chave pessoal Bitwarden em `Settings → Security → Keys → Rotate API Key`. - Nenhuma das duas credenciais expostas poderá ser usada nem no bootstrap. - Criar depois credenciais específicas de machine account no Bitwarden Secrets Manager. 2. **Resolver a raiz Git local** - `F:\PROGRAMADOR\VPSNOVA` será um repositório novo, privado e autônomo. - Como hoje a pasta ainda resolve para o repositório-pai perigoso `F:\PROGRAMADOR`, nenhum comando Git ou documento importante será gravado ali antes da autorização específica para criar a raiz isolada. - Após a criação, `git rev-parse --show-toplevel` deverá retornar exatamente `F:\PROGRAMADOR\VPSNOVA`. - O remoto canônico será um repositório privado no GitHub. 3. **Atualizar e proteger a VPS** - Aplicar atualizações pendentes e reiniciar antes do runtime. - Criar usuários separados: `admin`, `deploy`, `odds`, `hermes` e `backup`. - Instalar chave SSH e validar uma segunda sessão independente. - Instalar Tailscale e validar acesso e console de emergência. - Só depois desativar login de `root` e autenticação por senha. - UFW com política `deny` de entrada; SSH e API somente pela tailnet. - Nenhum dashboard ou banco escutando publicamente. 4. **Migrar `oddsbet.tech` para Cloudflare** - Como a zona não possui serviço ativo, executar a migração no início. - Exportar/inventariar primeiro todos os registros da Hostinger. - Cadastrar a zona na Cloudflare, comparar registros e trocar nameservers. - Validar propagação e manter procedimento de reversão. - Reservar: - `hermes.oddsbet.tech` - `ops.oddsbet.tech` - `memory.oddsbet.tech` - Os três serão publicados apenas via Cloudflare Tunnel + Access; o túnel usa conexões de saída e não exige portas web abertas na origem. [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/) 5. **Hostinger MCP somente no plano administrativo** - Instalar no computador administrativo, não dentro da VPS de produção. - Habilitar apenas `hostinger-domains-mcp`, `hostinger-dns-mcp` e `hostinger-vps-mcp`. - Não habilitar `billing`, `reach` ou `hosting`. - Preferir OAuth interativo para ações manuais; automação futura usa token novo vindo do Bitwarden. - Toda alteração DNS passa antes por inventário, validação e diff. [MCP oficial da Hostinger](https://github.com/hostinger/api-mcp-server) ## 3. Arquitetura de execução ```text collector- ─┐ collector- ─┼─> ingest-core ─> estado/deltas ─> api-read ─> Tailscale ─> backend do painel OddsPapi ─ resolver┘ │ └─> raw comprimido ─> compactação horária ─> S3 systemd/watchdogs ─> saúde e reinícios determinísticos Hermes ─> diagnóstico, insights, diffs e remediações allowlisted ``` ### Runtime híbrido - Hermes roda nativamente sob usuário próprio e systemd. - Odds, API, armazenamento, simulador e observabilidade rodam em Docker Compose. - Contêineres não reservam CPU/RAM antecipadamente; recebem limites máximos. - Cada fonte ativa tem um serviço/contêiner próprio, reutilizando a mesma imagem e runtime comum. - Fontes desligadas não consomem CPU/RAM. - Collectors nunca acessam o banco diretamente; enviam envelopes ao `ingest-core`, único escritor lógico. - Watchdogs, healthchecks e reinícios permanecem determinísticos e independentes de LLM. ### Serviços - `ingest-core`: valida, resolve identidades, persiste captura, estado e outbox de eventos. - `api-read`: API somente leitura para painel e simulador. - `collector-`: transporte e parser isolados por fonte lógica. - `history-compactor`: gera histórico horário em Parquet. - `backup-sync`: sincroniza raw, manifests e backups para S3. - `contract-simulator`: simula um backend consumidor, quedas e retomadas. - `grafana` + `prometheus` + exporters: painel operacional inicial. - Logs inicialmente estruturados em JSON, com rotação local; Loki só entra após medir recursos. Se entrar, usará Grafana Alloy, pois Promtail já está EOL. [Grafana Alloy](https://grafana.com/docs/loki/latest/send-data/alloy/) - OpenViking fica em um perfil Compose separado. ### Catálogo das 24 fontes O registry canônico conterá os aliases comprovados: Altenar/EstrelaBet, DataBet/Pitaco, BetConstruct/VBet, NGX/Lottu, Betano, Bet365, BaseHub/EnergiaBet, BrasilBet, Superbet, Betnacional, BWIN/Sportingbet, Kaya/WJ, FSSB/Betão/7K, SA Esportes/Lance de Sorte, BetBy/Betboom, BetMGM, Esporte da Sorte, KTO, Brazino777, Sporty, Milhão, Pinnacle, BetMexico/Aposta.bet e Matchbook. ## 4. Contrato USOS-2 e API pública interna ### Identidades - `fixtureId`: UUID estável interno, independente de qualquer fornecedor. - `identities[]`: IDs externos com `namespace`, `provider`, `nativeId`, evidência e confiança. - OddsPapi e Sportradar, quando disponíveis, são evidências de resolução; nenhum ID externo substitui silenciosamente o ID canônico. - Fuzzy matching nunca gera correspondência final automaticamente; resultados incertos ficam em `UNMATCHED/NEEDS_REVIEW`. A identidade do mercado será uma tupla estruturada, não um label: - esporte; - período; - família/stat unit; - escopo; - linha; - variante; - combinação; - UOF ID e specifiers quando existentes. `marketKey` será uma representação derivada dessa tupla. Os campos estruturados permanecem autoritativos. `outcomeKey` será derivado de lado/designação estruturada e nunca apenas do texto exibido. ### Observações de odds Cada outcome conterá `observations[]`. Cada observação inclui: - origem própria ou OddsPapi; - casa/provedor e IDs nativos; - preço decimal validado e preço nativo preservado; - estado `OPEN`, `SUSPENDED`, `CLOSED` ou `REMOVED`; - `capturedAt`, `fetchedAt` e idade calculada na leitura; - limite/order book/betslip quando disponíveis; - `rawRef` e SHA-256 da captura; - confiança, warnings e flags de validação. Política de seleção: 1. usar a observação própria mais recente e válida; 2. se ela não existir, permitir OddsPapi como fallback; 3. marcar sempre `fallbackUsed`, origem e idade; 4. preservar ambas quando existirem, sem sobrescrever divergências; 5. nunca arredondar preços no pipeline intermediário. Observações com decimal `<= 1`, overround fora de `[1.00, 1.25]`, `LABEL_FALLBACK` ou baixa confiança ficam preservadas em quarentena, mas não viram observação efetiva. ### Frescor - Coletor direto: alvo inicial em torno de 60 segundos. - Fonte frágil/browser: alvo inicial em torno de 180 segundos. - Jitter e backoff específicos por fonte. - Após 5 minutos sem captura válida, a fonte/observação vira `stale`. - Dados stale continuam auditáveis, mas `effectiveObservation` passa a `null`. - O consumidor decide visualmente o que mostrar; o serviço garante estado e tombstone. ### Endpoints v1 - `GET /api/v1/health/live` - `GET /api/v1/health/ready` - `GET /api/v1/sources` - `GET /api/v1/fixtures` - `GET /api/v1/fixtures/{fixtureId}` - `GET /api/v1/offers?fixtureId=&source=&marketKey=` - `GET /api/v1/delta?cursor=` - `GET /api/v1/stream?cursor=` — SSE - `GET /api/v1/unmatched` — somente administração - `GET /metrics` — somente rede interna Regras de transporte: - REST é a autoridade para snapshot e recuperação. - SSE entrega `upsert`, `remove`, `source_status` e heartbeat. - Cada evento SSE possui um cursor monotônico. - Heartbeat a cada 15 segundos. - Reconexão curta usa `Last-Event-ID`. - Gap ou cursor expirado obriga `GET /delta`; se necessário, novo snapshot. - Eventos delta ficam recuperáveis por 7 dias. - Paginação padrão de 100 e máximo de 500 registros. - Toda resposta informa `schemaVersion` e `snapshotVersion`. - Autenticação servidor-a-servidor combina ACL Tailscale e token read-only armazenado no Bitwarden. - O navegador nunca acessa diretamente a VPS de odds. O contrato será entregue em JSON Schema, modelos Python, OpenAPI, exemplos golden e consumidor de referência. ## 5. Persistência, retenção e benchmark ### Escolha SQLite versus PostgreSQL A implementação terá uma interface de persistência única e migrations equivalentes. O benchmark decidirá mecanicamente: SQLite WAL será aceito somente se, sob replay a quatro vezes a carga esperada e até oito fontes simultâneas: - houver exatamente um escritor lógico; - `p95` de transação de escrita ficar abaixo de 30 ms; - erros `busy/locked` ficarem abaixo de 0,1%; - `p95` de leitura principal ficar abaixo de 250 ms; - banco quente projetado ficar abaixo de 20 GiB; - backup consistente e restore limpo passarem; - API/SSE mantiverem cursor sem gap; - restarem ao menos 30% de RAM e disco livres. Se qualquer limite falhar, se o resultado for inconclusivo ou se mais de oito fontes forem promovidas, a primeira produção usa PostgreSQL. ### Retenção - Estado atual: permanente enquanto relevante. - Raw comprimido local: 7 dias. - Raw comprimido no S3: 30 dias. - Histórico normalizado: Parquet particionado por `date/hour/source`. - Compactação horária com baixa prioridade de CPU/I/O. - Backup diário das odds e estado. - Backup antes de deploy/migração. - Hermes e OpenViking: backup diário consistente. - Configuração, mapas e decisões: GitHub privado. - Nenhuma remoção local ocorre antes de upload, manifesto e hash verificados. - Um restore isolado deve concluir em até quatro horas. - Como não haverá dados de usuários nesta fase, aceita-se perda máxima de 24 horas para odds históricas; isso deverá ser revisto antes de armazenar dados pessoais. ## 6. Hermes, memória e painéis ### Hermes - Instalação oficial fixada em versão, sob usuário `hermes`. - Login ChatGPT/Codex por device OAuth; `~/.hermes/auth.json` e `~/.codex/auth.json` tratados como senhas. - Dashboard oficial em `127.0.0.1:9119`, publicado somente por Cloudflare Access. [Dashboard Hermes](https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/features/web-dashboard.md) - Telegram no primeiro go-live. - WhatsApp somente depois de o Telegram estar estável; a integração usa ponte Web/baileys e será tratada como experimental. - SSH/CLI permanece canal de contingência. Permissões: - Ler métricas, health e logs sanitizados. - Executar wrappers allowlisted para `status` e restart de coletores específicos. - Preparar alterações em clone de desenvolvimento isolado, rodar testes e gerar diff. - Não acessar Docker socket. - Não ler todos os segredos. - Não alterar firewall, SSH, DNS ou pacotes. - Não fazer push, merge, deploy ou rollback de produção. - Toda remediação automática gera log, motivo, serviço, resultado e recuperação. ### Memória compartilhada - Memória built-in do Hermes continua privada. - A instância começa vazia. - O pacote inicial será inserido manualmente: arquitetura, contrato, catálogo, limites do agente e runbooks aprovados. - Git continua sendo a fonte de verdade; memória nunca substitui documentação versionada. - OpenViking self-hosted será desenvolvido em paralelo, com: - conta `oddsbet`; - recursos compartilhados do projeto `vpsnova`; - usuários e peers separados para Hermes, Codex, Claude e futuros agentes; - acesso MCP/API somente por rede privada/BFF; - Web Studio atrás de Cloudflare Access; - export/backup testado. - O front administrativo nunca recebe chave do OpenViking. - OpenViking só é ativado permanentemente na VPS se o modelo local e o serviço permanecerem dentro de 1 vCPU, 3 GiB de RAM e não degradarem a API em mais de 10%. - Caso falhe, permanece no desenvolvimento local ou migra para outra máquina; nenhuma API paga será contratada implicitamente. [OpenViking multi-tenant](https://github.com/volcengine/OpenViking/blob/main/docs/en/concepts/11-multi-tenant.md) ### Observabilidade - Grafana OSS auto-hospedado, sem assinatura, acessível por `ops.oddsbet.tech`. [Grafana OSS](https://grafana.com/docs/learning-hub/which-grafana/02-understand-your-options/03-grafana-oss/) - Prometheus com retenção limitada a 7 dias/2 GiB. - Dashboards: - CPU, RAM, disco e rede; - estado dos contêineres; - captura válida por fonte; - frescor, falhas e backoff; - raw/parsed/valid/rejected; - volume de unmatched/quarentena; - latência ingestão→API/SSE; - crescimento diário de disco; - status de backup e último restore. - Alertas e recuperações enviados ao Telegram. ## 7. Desenvolvimento, documentação e deploy sem sobreposição Depois do gate Git, `F:\PROGRAMADOR\VPSNOVA` conterá: - `README` e estado atual validado. - ADRs e arquitetura. - Contrato/schema/OpenAPI. - Registry e dossier das 24 fontes. - Runbooks de SSH, Tailscale, Cloudflare, Hermes, backup, restore, incidente e rollback. - Evidências de probes, benchmarks e soak. - Infraestrutura Compose/systemd. - Código, testes, corpus golden reduzido e simulador. - Ledger cronológico de mudanças e deploys. Fluxo multidev: - Uma branch e worktree por pessoa/agente. - `main` protegida e sem push direto. - PR com replay, schema, contrato e testes. - Proibição de force-push e de `git add .`/`git add -A`. - Alterações derivadas de BETMONITOR/PACIFICADORPROP são copiadas conscientemente, com origem documentada; esses repositórios não viram runtime. Deploy inicial: 1. Exigir commit limpo e revisado. 2. Construir imagens imutáveis e manifest com commit/tag/hashes. 3. Adquirir lock exclusivo de deploy na VPS. 4. Rejeitar deploy concorrente ou release divergente. 5. Instalar em `/opt/vpsnova/releases/`. 6. Testar migrations e canário. 7. Promover atomicamente `current`. 8. Manter `previous` para rollback. 9. Registrar operador, horário, release e resultado. 10. Migrar depois para GitHub Actions reutilizando exatamente o mesmo pipeline e mantendo promoção manual. ## 8. Rollout das fontes Estados oficiais por fonte: 1. `catalogued`: inventário/raw identificado. 2. `structured_only`: parser passa corpus golden e schema. 3. `network_ready`: transporte direto funciona a partir da nova VPS. 4. `runtime_ready`: serviço contínuo e soak individual de 24 horas. 5. `panel_ready`: contrato e simulador passam sem perda. 6. `prod_enabled`: promoção explícita e monitorada. Regras: - Schema e replayer vêm antes de qualquer monitor. - Direct HTTP/WS/SSE primeiro. - Proxy residencial somente após bloqueio comprovado e aprovação. - Browser/Chrome/Playwright apenas por análise individual, isolado e sem AdsPower. - Uma fonte entra por vez. - A primeira onda não tem número ou nomes obrigatórios; é formada pelas fontes que passarem os gates. - Empates de prontidão priorizam: daemon direto existente, maior cobertura golden, menor dependência de browser e menor consumo. - Após a primeira fonte: soak de 24 h. - Após o primeiro lote: soak conjunto de 72 h. - A expansão para novas fontes para quando RAM sustentada superar 70%, CPU p95 superar 65%, disco livre cair abaixo de 30% ou a API sair dos SLOs. - As 24 fontes podem permanecer em estágios diferentes; “estrutura para 24” não significa “24 online”. ## 9. Testes e critérios de aceite ### Segurança - As duas credenciais expostas foram revogadas. - Nenhum segredo aparece em Git, documentação, logs ou imagem Docker. - Bitwarden Secrets Manager usa machine accounts separadas para `local-deploy`, `vps-prod` e futura `github-actions`. [Bitwarden machine accounts](https://bitwarden.com/help/machine-accounts/) - Login por chave validado em segunda sessão. - Root e senha SSH desabilitados. - Nenhuma porta de API/dashboard/banco pública. - Cloudflare Access e ACL Tailscale testados. - Hermes não consegue acessar Docker socket, segredo de produção ou deploy. ### Contrato e dados - Todo raw golden das 24 fontes é reproduzível por hash. - Nenhuma odd publicada sem origem, `fetchedAt`, estado e raw reference. - OddsPapi nunca mascara captura própria. - Fuzzy incerto nunca produz match automático. - `UNMATCHED` permanece preservado. - Duplicação e reprocessamento são idempotentes. - Preço nativo não sofre arredondamento intermediário. - Tombstone remove odds fantasmas. ### Desempenho e operação - Ingestão validada→estado: p95 abaixo de 100 ms. - Consulta principal: p95 abaixo de 250 ms. - Estado commitado→SSE: p95 abaixo de 3 s. - Metas de captura: aproximadamente 60 s direto e 180 s frágil/browser. - Reinício forçado de contêiner não perde cursor. - Reboot da VPS recompõe os serviços aprovados. - Desconexão SSE forçada recupera estado terminal sem buraco nem duplicação semântica. - Crescimento diário de disco é medido antes de promover nova fonte. - Backup S3 e restore completo são provados antes do go-live. ### Aceite final da primeira fase A primeira fase estará pronta quando: - host estiver endurecido; - repositório e documentação estiverem seguros; - contrato USOS-2 v1 estiver congelado; - benchmark tiver escolhido banco; - API REST/SSE e simulador estiverem aprovados; - ao menos uma fonte tiver chegado a `prod_enabled`; - Grafana, Hermes/Telegram, backups e rollback estiverem operacionais; - OpenViking puder continuar em paralelo sem impactar a entrega de odds. ## Premissas finais - A VPS atual é Ubuntu 24.04, 4 vCPU, 15 GiB RAM, ~193 GiB e Docker já instalado. - O painel externo permite Tailscale. - `oddsbet.tech` não possui serviço atual a preservar. - Operador inicial único; RBAC preparado para equipe. - Não haverá dados de usuários nesta fase. - Não há alta disponibilidade física; expansão futura poderá separar banco, API, browsers, observabilidade e memória sem mudar o contrato. - Este turno não executa mudanças nem escreve documentação; a primeira ação de execução será resolver credenciais e a raiz Git segura.