Vigia as contas oficiais de IA no X, decide o que importa para cada grupo, e avisa na voz certa — código para a mecânica, uma LLM só para o julgamento.
Em uma frase
Quando a Anthropic ou a OpenAI anuncia algo no X — um modelo novo, uma capacidade, uma mudança de preço — o radar percebe em segundos, decide se aquilo interessa a cada um de dois grupos de WhatsApp, e, se interessar, escreve e posta um resumo na voz apropriada de cada grupo: caloroso e simples para a família que está aprendendo IA; técnico e direto para a equipe de desenvolvimento.
Roda sozinho, 24 horas por dia, num servidor. Ninguém precisa acompanhar o X. O trabalho todo é: captar o sinal, separar do ruído, e entregar no tom certo — sem repetir a mesma notícia e sem incomodar de madrugada.
A ideia central
Este é o princípio que organiza tudo o resto — e foi uma virada consciente. A primeira versão deixava a LLM orquestrar o processo inteiro: decidir relevância, postar, confirmar que saiu, deduplicar. Parecia natural ("a IA é inteligente, deixa ela cuidar"), mas era frágil: a LLM é não-determinística e não tem como provar que uma mensagem foi entregue — ela só afirma que foi. O fluxo virava uma costura de linguagem natural, cheia de pontos onde algo se perdia ou se repetia.
A resposta foi separar as duas naturezas de trabalho. Há decisões que pedem julgamento — "isso é relevante para a família?", "como escrever isso de um jeito que a equipe de dev valorize?" — e a LLM é ótima nisso. E há decisões que pedem execução mecânica — "já mandei esse tweet?", "estamos dentro do horário?", "o envio deu certo?" — onde o que se quer é um protocolo determinístico, verificável e testável. Código é melhor nisso.
Recebe um post, decide se é relevante para cada grupo, e — se for — escreve a mensagem pronta na voz daquele grupo. Devolve um JSON CLASSIFICACAO. Não posta, não deduplica, não confirma nada.
Janela de horário, dedup, envio, tratamento de falha — em código determinístico, coberto por testes. O parecer da LLM é tratado como dado não-confiável e revalidado antes de qualquer uso.
Como funciona
Cada post das contas oficiais atravessa este pipeline. A ideia-guia: a durabilidade vem primeiro — o post é gravado em disco antes de qualquer decisão, então nada se perde se o processo cair no meio.
A cada post novo de @AnthropicAI · @claudeai · @ClaudeDevs · @OpenAI, o provedor dispara um webhook para o servidor.
at-least-onceAutentica, valida os tipos, filtra a conta, e grava o post no outbox (fila em disco) de forma atômica. Responde rápido ao provedor.
outbox durávelO worker entrega o post ao classificador LLM isolado, que devolve, por grupo: relevante? e o texto pronto. O parecer é gravado no outbox.
só julgaProjeto IA — família, manchete calorosa 🍡
Sidlar Desenv — equipe, manchete sóbria 📡
O ponto sutil está entre a estação 3 e a 4: quando o classificador devolve o parecer, o worker grava esse parecer no outbox antes de tentar enviar. Assim, se o envio para um grupo falha e a máquina reinicia, na retomada o worker reusa o parecer que já estava no disco — não pede uma nova classificação à LLM (que poderia mudar de ideia e abandonar o grupo que faltava). Classifica-se uma vez por notícia, não a cada tentativa.
O resultado
A mesma notícia, escrita duas vezes pela LLM — cada uma na voz do seu grupo. Toda mensagem abre por uma manchete de uma linha que já diz o quê (nunca o quando: a entrega pode atrasar horas pela janela e pela fila), depois o corpo. O selo identifica de relance que é notícia: 🍡 para a família, 📡 para a equipe.
A manchete é redação, não um selo fixo colado pelo código — quem a escreve é a mesma LLM que escreve o corpo, respeitando a voz de cada grupo. Na família ela já entrega o "tipo" da notícia de graça ("Saiu modelo novo"); na equipe, o selo 📡 e o negrito nos termos técnicos dão o tom de comunicado.
As peças
Componentes pequenos e testáveis, cada um com um papel claro. O estado do sistema é modesto: essencialmente uma lista de "o que eu já mandei".
A porta de entrada e o motor. Recebe o webhook, mantém o outbox durável e roda o laço do worker.
redrive/health: denuncia trava, backlog e DLQA lógica determinística. Classifica uma vez, valida o parecer e entrega grupo a grupo.
pbs.twimg.comA memória: quem já foi avisado. Um registro de IDs por grupo, gravado de forma atômica.
tweet_id já enviados, por grupoflock)A saída. Chama o message send do OpenClaw e responde uma pergunta só: dá pra parar de tentar?
O elo com a LLM. Manda o post ao agente radar e extrai o CLASSIFICACAO da resposta.
openclaw:radar)O critério, em linguagem natural: o que vale para cada grupo, em que voz. É o único lugar "inteligente".
CLASSIFICACAO por grupoO contrato
Esta é a decisão mais importante do projeto, e ela é deliberada. O ideal seria "cada notícia chega exatamente uma vez" (exactly-once). Mas isso é impossível de garantir quando o destino — o WhatsApp — não oferece uma chave de idempotência: não há como enviar e ter certeza absoluta, atômica, de que chegou. Toda tentativa de forçar essa garantia (confirmar por log, reenviar na dúvida) abria um buraco novo.
Então escolhemos o caminho simples e honesto: at-most-once. Em caso de dúvida, o sistema não reenvia. A regra de envio cabe em uma linha: se o envio deu certo (ou deu timeout, e pode ter ido), marca como feito e nunca mais toca; se deu um erro claro de "não conectou", tenta de novo mais tarde. O estado que impede a repetição é aquela lista simples de IDs já enviados.
Para um radar de notícias, essa é a troca certa: uma duplicata visível irrita e mina a confiança; uma notícia perdida é rara, invisível, e você a descobre por outro canal. Melhor calar na dúvida.
o que o sistema sustenta sempre
pbs.twimg.com; texto vai como argumento, sem shell.falhas conscientes, não bugs
O laço do worker
Dentro da janela de horário, o worker consome o outbox item a item. Este é o percurso de um post relevante — e os desvios quando algo dá errado.
message send. Deu certo (ou timeout) → marca feito e nunca reenvia. Terminou os dois grupos → o post sai do outbox.redrive devolve os itens à fila normal — com o parecer preservado. Nada se apaga; tudo se reprocessa.Quando algo quebra
O oposto do perigoso não é "nunca falha" — é "nunca falha em silêncio". Cada modo de falha tem um sinal observável.
O worker dorme e os posts esperam no outbox. É o comportamento normal da janela — não é fila travada.
A classificação não gasta tentativa (a falha é do transporte, não do post). Ao voltar, a fila drena sozinha; o /health acusa "sem progresso".
Um post que sempre falha esgota um contador e vai para a DLQ, sem travar os outros. A DLQ acende o /health (500).
Se o arquivo de dedup fica ilegível, o sistema para em vez de republicar no escuro — e o /health denuncia na hora.
A história
O sistema atravessou uma re-arquitetura e nove rodadas de revisão adversarial (Codex). O padrão que emergiu: o caminho crítico resistiu; cada mecanismo novo precisou da própria rodada.
Webhook → o agente decide, posta, confirma e deduplica. Uma revisão adversarial mostrou que a "costura por linguagem natural" perdia e duplicava sob concorrência e queda.
O código assume a mecânica; a LLM fica com o julgamento. Some a classe de bugs de costura. Cada peça vira testável de verdade.
Percebemos que perseguir "exatamente uma vez" era caro e impossível. Trocamos por "nunca duplica, aceita perder raro" e removemos a máquina de estados inteira — ⅔ do código e a maioria dos bugs sumiram com a superfície.
Nove passadas adversariais. O núcleo (recepção, dedup, envio, janela) resistiu a ataque direto; os achados restantes eram de operabilidade — recuperação de falha, uma corrida rara. Cada um virou um teste.