PROJETO · HISTÓRICO DE VERSÕES

Changelog

Todas as mudanças importantes do projeto, em ordem reversa cronológica. Formato segue Keep a Changelog; versões em SemVer.

Histórico de versões

Registro cronológico de tudo que mudou no painel — dados, metodologia e interface —, da versão mais recente para a mais antiga.

Página 6 de 12 · 136 versões no total.

  1. v4.15.0 2026-08-10 Share of voice, o custo da opinião e resumos com memória

    Added

    • Share of voice semanal no Cenário Semanal: fatia de cada candidato no total de artigos por semana fechada desde abril, com as trocas de liderança marcadas no gráfico — o dado limpo revela que Flávio Bolsonaro assumiu a liderança de volume em quatro semanas (11/05, 22/06, 06/07 e 20/07) e Lula retomou nas quatro seguintes. Série que nenhuma página mostrava.
    • "O custo da opinião" na página de candidato: sentimento médio por gênero jornalístico (notícia, análise, opinião, entrevista). O gênero era classificado a cada coleta desde abril e nunca havia sido cruzado com candidato.
    • Grafo candidato↔tópico colorido por sentimento: a cor da aresta agora indica o tom médio daquele candidato naquele tema — o grafo vira mapa de vulnerabilidade e força por assunto. Barras de Zeitgeist do detalhe também ganham o tom por cluster.
    • Resumos editoriais (SapiensLabs) com três dimensões novas: linha editorial em 5 níveis (antes 3), gênero jornalístico com sentimento, e comparação com a janela anterior (volume + tom) — o prompt sempre pediu comparação temporal e o dado nunca chegava.

    Fixed

    • Página de candidato 14× mais rápida (5-6s → ~0,4s): a função que monta o detalhe rodava ~12 consultas agregadas a cada visita, sem cache — na página que mais recebe compartilhamento. Cacheada e incluída no aquecimento pós-coleta.

  2. v4.14.0 2026-08-10 Espectro em 5 níveis, janelas justas e a página que abre no presente

    Added

    • Espectro Editorial em cinco níveis — da extrema-esquerda à extrema-direita. A página colapsava a classificação detalhada (produzida a cada coleta desde abril) em três níveis grossos, somando os extremos aos vizinhos — exatamente onde mora o sinal mais forte do banco: a cobertura de Flávio Bolsonaro cresce monotonicamente da extrema-esquerda (-0,60) à extrema-direita (+0,27), e a de Lula é o espelho invertido (+0,25 na esquerda → -0,48 na extrema-direita). Renan Santos é o desviante: positivo no centro E na direita. Agregadores e veículos sem classificação ficam fora do espectro, com contagem declarada em rodapé.
    • Janela "48h" no Cenário Geral e pills reordenadas do presente para o passado (Hoje → 48h → 7 dias → ... → Tudo). A página passa a abrir nos últimos 7 dias — o padrão anterior ("Tudo") diluía o momento em cinco meses de série.

    Fixed

    • Comparações "vs anterior" agora usam o mesmo período da janela anterior (apontado pelo Leo): na segunda-feira, compara-se com a segunda anterior; na terça, com segunda+terça; no domingo converge para a semana cheia — idem no mês, dia a dia. Antes, a janela corrente PARCIAL era comparada com a anterior INTEIRA: toda segunda de manhã o painel mostrava o campo inteiro "em queda de 90%", número que só fechava no domingo. A correção foi feita na fonte e alcança todos os consumidores: "Quem sobe · quem desce" da capa, grid e KPIs do Cenário Semanal, KPIs mensais, candidato em destaque, gráfico dumbbell e tópicos emergentes. Rótulos atualizados para dizer o que o número de fato é.

  3. v4.13.0 2026-08-10 Fase 1 da revisão de campanha: capa quente, URL /candidatos e SEO

    O dashboard vira a chave da era pré-campanha para a campanha (propaganda começa 16/08).

    Added

    • Capa quente. KPIs "Artigos hoje" e "Tom da semana" (sentimento médio ponderado por volume); seção "Quem sobe · quem desce" (top-3 altas e quedas de volume da semana vs anterior, piso de 10 artigos); seção "A semana em dois extremos" (manchetes mais negativa e mais positiva do candidato com cobertura mais dividida, rotuladas como leitura do classificador, linkando às fichas internas). Tudo derivado de dados que o painel já calculava — nada de coleta ou query nova.
    • Contagem regressiva para o 1º turno (04/10/2026) e carimbo de última coleta na sidebar — visíveis em todas as páginas. Antes, 11 das 14 páginas não tinham nenhum sinal de frescor.
    • Cartão social (og:image) e metadados completos: description, canonical, og:title/description/url/image e twitter:card em todas as páginas. Compartilhar qualquer página do painel deixa de gerar cartão cinza sem informação.

    Changed

    • URL do índice de candidatos migrada: /pre-candidatos/candidatos, com redirect 301 permanente nas URLs antigas (links salvos continuam funcionando). Com 13 candidatos oficiais e 0 pré-candidatos, a URL antiga era a etiqueta da fase anterior em toda página compartilhada.
    • Navegação reordenada: Espectro Editorial sobe (é a página mais eleitoral do painel); API pública sobe para o grupo Análise; Zeitgeist e Análises formam o grupo "Aprofundamento"; Radar sai do menu (a rota continua acessível por link direto) — num campo de 13 candidatos, um gráfico limitado a 3 com eixos de normalização relativa induzia mais confusão que leitura.
    • Espectro e Comparativo agora abrem com os 13 candidatos — o padrão anterior (top-5 por volume) escondia 8 candidaturas oficiais da visão inicial, um viés de exposição herdado da era pré-campanha.
    • Página de candidato descontinuado: rótulo correto ("FORA DA CORRIDA" — antes dizia "PRÉ-CANDIDATO") e noindex (fica no ar como contexto histórico, fora do índice de busca).
    • Sitemap com lastmod honesto: páginas de dados carregam a data do último snapshot; páginas estáticas, a da última edição real (antes tudo dizia "hoje" — sinal de baixa confiança para buscadores).
    • Metodologia atualizada: título próprio ("Metodologia"), remoção da promessa vencida de validação em julho, dos canais desligados (Tavily) e de fontes removidas (Jornal Opção); modelo editorial corrigido para Opus 5.

  4. v4.12.0 2026-08-10 Fase 0 da revisão de campanha: estanca a fuga de dados do verificador

    Primeira leva da revisão de fase para o início da campanha eleitoral (16/08). Diagnóstico completo em três auditorias (dashboard, dados, pipeline) precedeu este lote — as mudanças abaixo atacam o que corrompia dados publicados.

    Fixed

    • Verificador sem janela temporal — corrige fuga estrutural que tornava candidatos pequenos invisíveis. A janela --horas 3 filtrava por a.fetched_at (timestamp do artigo), mas os coletores criam vínculos novos em artigos velhos no caminho de duplicata: o vínculo nascia verified=0 já fora de qualquer janela futura e nunca mais era verificado — logo, nunca aparecia no dashboard nem nos resumos (que filtram verified=1). Em 10/08, eram 9.407 pares invisíveis (100% deles com created_at > fetched_at), com perda REGRESSIVA: 54,7% dos pares de Edmilson Costa invisíveis, 51,4% de Samara Martins, 46,4% de Hertz Dias — contra 4,2% de Lula. O ranking publicado subestimava os candidatos pequenos em 20-55%. Agora o verificador processa WHERE verified = 0 sem janela (imune também ao desalinhamento UTC/localtime de created_at), a limpeza de órfãos idem, e o alerta do Telegram ganhou o campo Pendentes — invariante 0; qualquer valor ≠0 acusa a fuga na hora. --horas é aceito e ignorado (deprecado).
    • Body scraping deixa de re-baixar falhas permanentes. Coluna nova articles.body_status: 401/403/404/410 e paywall-sem-corpo são marcados 'permanent' e saem do SELECT. Antes, 5.478 artigos mortos eram re-baixados a cada coleta — ~2h30 de trabalho perdido por run, 3× por dia. A coleta cai de ~2h20 para menos de 1h.
    • Google News cobria só 8 dos 13 candidatos. Entraram Augusto Cury, Edmilson Costa, Hertz Dias, Rui Costa Pimenta e Samara Martins (com partido na query para os homônimos fortes); saíram 6 chaves de descontinuados. Os quatro mais ausentes eram os mesmos que mais perdiam na fuga do verificador — os dois defeitos se compunham.
    • Patterns que morreriam em 16/08. Quatro candidatos usavam pré-candidato como desambiguador de sobrenome; quando a imprensa passar a escrever só "candidato", esses ramos morreriam em silêncio (RSS e sitemaps dependem 100% dos patterns). Agora aceitam (pré-)?candidato, nas duas direções para Zema e Caiado ("o candidato Zema"). Vices entraram como desambiguadores dos titulares: Kassab→Caiado, Girão→Zema, Gaspar→Flávio, Delgado→Cury, Medina→Renan, Torquato→Clariana, Tenente Dalma→Avalanche, Vanessa Portugal→Hertz, Cleusa→Edmilson, Brício→Samara, Antônio Carlos Silva→Pimenta. "Chapa Caiado-Kassab é registrada no TSE" agora casa. 11 casos de teste novos (27 no total).
    • Prompt do sentimento ensinava a oposição errada. Citava Tarcísio e Michelle (ambos fora da corrida) como exemplos canônicos de oposição e nunca mencionava Flávio Bolsonaro — o 2º maior volume do banco. Agora traz o contexto real da corrida (governista Lula; oposição liderada por Flávio, com Caiado/Zema/Renan/Cury) e regra explícita para Jair/Michelle Bolsonaro (não-candidatos; só afetam Flávio com conexão explícita no texto). Prompt do verificador idem: Leite (dropped) removido, Caiado/Zema como ex-governadores, homônimo "Avalanche" documentado. Quebra leve de comparabilidade: sentimento de artigos sobre "oposição" difusa tende a deslocar de Tarcísio/Michelle para Flávio a partir desta versão.

    Changed

    • Vocabulário de fase na coleta. O grupo _geral do Google News ganhou 5 queries que não existiam em nenhuma camada: debate presidencial, pesquisa eleitoral, registro no TSE, horário eleitoral e propaganda eleitoral. O funil continua exigindo match de candidato — as queries alargam recall sem criar lixo.
    • Feeds mortos removidos (Carta Capital e Jornal Opção — 403 permanente desde julho; cobertura preservada via Google News/sitemap). O campo Fontes off do alerta volta ao piso 0 e passa a indicar falha real.
    • Docstrings e logs dos produtores atualizados para o modelo real (gemini-3.1-flash-lite) — diziam Ollama/Gemma4/Gemini 2.5 desde abril.

  5. v4.11.14 2026-08-07 Campo fecha em 13: Clariana Barão e Rui Costa Pimenta oficializados; 3 vices atualizados

    Changed

    • Clariana Barão (DC) → candidate. Convenção nacional em 05/08/2026, em São Paulo, com a advogada Fabiana Torquato na vice — chapa 100% feminina. É a primeira vez desde a fundação do DC, em 1995, que o candidato à Presidência não é o fundador José Maria Eymael. Múltiplas fontes com data e local: Blog do Mário Flávio, capitalnews, Congresso em Foco, Folha, Metrópoles.
    • Rui Costa Pimenta (PCO) → candidate. Mantido pre-candidate desde 04/08 por falta de convenção datada por fonte primária. Passadas 48h do prazo legal, manter esse status deixou de ser neutro: todo roundup pós-05/08 (Metrópoles, CartaCapital — "lista final… 13 chapas", em.com.br, Goiás 246, gauchazh, El Universal) o trata como candidato assentado, sem hedge algum — contraste nítido com Cabo Daciolo (explicitamente excluído por todas as fontes) e com a própria Clariana antes de sua convenção ("deve lançar"). dropped não se aplica: nada indica saída da corrida. A ambiguidade genuína foi para a notes, não para o status: o PCO não divulgou convenção nacional com data e local — o evento de 08/08/2026 em São Paulo é chamado pelo próprio partido de "lançamento", não convenção; a chapa (Antônio Carlos Silva "Toninho" na vice) foi escolhida na 38ª Conferência Nacional, instância interna.
    • 📝 Composição final: 22 monitorados = 13 candidatos, 0 pré-candidatos, 9 descontinuados. O campo das candidaturas presidenciais está fechado.

    Fixed

    • Três vices corrigidos de "indefinido" para nomeado, todos registrados nos dias seguintes ao prazo:
      • Flávio Bolsonaro (PL) — deputado federal Alfredo Gaspar (PL-AL).
      • Romeu Zema (Novo) — senador Eduardo Girão (Novo-CE); chapa já registrada no TSE em 06/08/2026.
      • Augusto Cury (Avante) — ex-deputado federal Júlio Delgado, que já vinha assessorando o candidato desde o início do ano.

    Reference

    • Achado que explica o padrão do PCO: um artigo regional (correiodopovo.com.br, 04/08) sobre a convenção estadual no RS registrou que o partido cumpre o prazo legal em nível estadual ("o PCO deve realizar sua convenção na quarta-feira"), mas revela os nomes da chapa nacional só no lançamento do dia 8. Isso é consistente com uma legenda pequena que separa o ato legal (convenção, silencioso pra imprensa) do evento de publicidade (lançamento, com data e local divulgados). Não achamos confirmação primária de que esse ato legal específico ocorreu até 05/08 para a chapa presidencial — a promoção se apoiou no peso da cobertura pós-prazo, não numa data de convenção.

  6. v4.11.13 2026-08-05 Fim do prazo das convenções: Cabo Daciolo barrado pelo Mobiliza

    Changed

    • Cabo Daciolo (Mobiliza) → dropped. O partido comunicou em 04/08/2026 que não lançaria candidato próprio, barrando a candidatura e deixando-o sem sigla no último dia do prazo de convenções. O próprio Daciolo reagiu, chamando a decisão de "decepção muito grande" em post que depois apagou (Poder360). Paralelamente, o PL do Amazonas passou a negociá-lo como candidato a vice-governador. ⚠️ A notes registra que a saída foi decisão da legenda, não desistência dele — distinção que importa caso isso reverta, e este roster já reverteu antes (Michelle Bolsonaro, abril→maio). Fontes: Poder360, A Tarde, Bahia Notícias.
    • Data da convenção de Leonardo Avalanche cravada em 30/07/2026. Em 4.11.12 a bio ficou sem o dia por divergência entre fontes (Poder360 registrava 29/07). Agora são duas fontes em 30/07 — G1 e Bahia Notícias/edmaisfm, esta última com o local junto ("Goiânia, no dia 30 de julho") —, o que satisfaz o mesmo critério de data + local exigido dos demais.
    • 📝 Composição atual: 13 monitorados ativos — 11 candidatos e 2 pré-candidatos (Clariana Barão, Rui Costa Pimenta); 9 descontinuados.

    Reference

    • Rui Costa Pimenta (PCO) — mantido pre-candidate, agora com evidência mais forte que em 4.11.11. A retrospectiva de Bahia Notícias/edmaisfm (05/08) lista os 12 candidatos confirmados e dá data e local de convenção para onze deles — Samara 26/07 SP, Zema 27/07, Avalanche 30/07 Goiânia, Hertz 31/07 SP, Edmilson 01/08 SP, Grassi 02/08 Rio, Cury 03/08 SP… — e para Pimenta traz apenas biografia, sem nenhuma menção a convenção. Não é ausência de cobertura: é ausência diferencial dentro de uma mesma fonte que tinha todo o motivo para incluir a data. Somado ao órgão do próprio PCO tratando-o como pré-candidato com lançamento marcado para 08/08, o critério segue não atendido.
    • Clariana Barão (DC) — mantida pre-candidate. Duas fontes de 05/08 (bra1, edmaisfm) informam que a convenção do DC ocorreria hoje, último dia permitido, e que ela "deve" ser lançada — redação de futuro. Não há registro de realização até o fechamento desta entrada (16h55). A busca externa devolveu só conteúdo indexado de julho, gotcha já documentado para candidato menor.
    • ⚠️ Lista de instituto de pesquisa não indica oficialização. A Quaest de 05/08 inclui "Clariana Barão (DC)" ao lado dos confirmados e omite Rui Costa Pimenta; a Meio/Ideia do mesmo dia faz exatamente o inverso. Institutos montam a lista pelo campo esperado, não por registro de convenção — não serve como evidência em nenhuma das duas direções.

  7. v4.11.12 2026-08-04 Dois candidatos entram no monitoramento: Leonardo Avalanche (PRTB) e Wilson Grassi (Democrata)

    Added

    • Leonardo Avalanche (PRTB) — Leonardo Alves de Araújo, empresário e bacharel em Direito, natural de Anápolis (GO). Preside o PRTB desde fevereiro de 2024 e coordenou a campanha de Pablo Marçal à Prefeitura de São Paulo naquele ano. Candidatura oficializada em convenção nacional em Goiânia, em chapa pura com a policial militar Tenente Dalma na vice. Entra direto como candidate. ⚠️ A bio não crava o dia da convenção: o Poder360 registra 29/07 (uma 4ª feira, coerente com o calendário) e o G1 registra 30/07 — divergência de um dia entre duas fontes de primeira linha, e o banco não tem relato primário do evento porque o candidato não era monitorado.
    • Wilson Grassi (Democrata) — médico veterinário paulista. Candidatura confirmada em 02/08/2026, em convenção nacional no Rio de Janeiro, vice ainda não definido. É a primeira vez que a legenda, fundada em 2008 e anteriormente chamada PMB, lança nome próprio à Presidência. Entra direto como candidate.
    • 📝 Composição atual: 14 monitorados ativos — 11 candidatos e 3 pré-candidatos (Cabo Daciolo, Clariana Barão, Rui Costa Pimenta); 8 descontinuados.

    Fixed

    • Lacuna de cobertura fechada. Ambos já constavam nas listas de presidenciáveis de Estadão, DW, Bloomberg Línea e CNN, e Avalanche aparecia em pesquisas Quaest/Datafolha desde meados de julho — o painel simplesmente não os enxergava, porque nenhuma query os buscava. Foram detectados lendo body_text na varredura de 04/08.

    Reference

    • ⚠️ Patterns tratados com cuidado extra por risco de falso positivo. "Avalanche" é palavra comum em português e o banco tem manchetes reais como "na avalanche de pesquisas", "publica avalanche de vídeos" e "Avalanche de crises sobre o bolsonarismo". Nenhum pattern usa \bavalanche\b isolado — todos exigem o primeiro nome, o nome civil ou co-ocorrência com PRTB. Mesmo tratamento para "Grassi", sobrenome comum. Smoke test cobre 5 positivos e 5 negativos extraídos de manchetes reais.
    • Pipeline retroativo executado (as 5 mudanças do procedimento + classificação): 84 pares associados pelo retroactive_scan.py; anti-FP escopado confirmou 67 e removeu 17 falsos positivos — todos do Avalanche, artigos onde ele aparece só na tabela de uma pesquisa, sem citação no título ou descrição; sentimento classificou 67/67 sem erro; topicos.py preencheu 199 tópicos por cópia, com 0 chamadas ao Gemini (efeito do fix de 4.11.8). Saldo: 63 pares verificados para Avalanche e 4 para Grassi.

  8. v4.11.11 2026-08-04 Augusto Cury oficializado; Michelle Bolsonaro fora da corrida presidencial

    Changed

    • Augusto Cury (Avante) oficializado candidato. Convenção nacional na noite de 03/08/2026, na Assembleia Legislativa de São Paulo (Alesp), com presença do governador Tarcísio de Freitas. Vice ainda não definido — quatro fontes registram a chapa incompleta a dois dias do prazo. Cury defendeu o semipresidencialismo e disse que convidaria Tarcísio para primeiro-ministro; afirmou também que a composição com Romeu Zema (Novo) está praticamente descartada. Fontes: Agência Brasil, Poder360, Congresso em Foco, InfoMoney, Jornal de Brasília.
    • Michelle Bolsonaro (PL) removida da corrida presidencial (registro da alteração feita no banco em 04/08, que não constava aqui). Em carta própria lida na convenção do PL em 02/08, confirmou que disputará o Senado pelo DF; o anúncio foi feito por Flávio Bolsonaro. É a segunda saída dela do painel — a primeira foi em 13/04/2026, pelo mesmo motivo, revertida em 13/05. Desta vez há declaração da própria, que é o critério ([[feedback_dropar_candidato_so_com_declaracao]]).
    • 📝 Composição atual: 12 monitorados ativos — 9 candidatos (Lula, Flávio Bolsonaro, Ronaldo Caiado, Renan Santos, Samara Martins, Romeu Zema, Hertz Dias, Edmilson Costa, Augusto Cury) e 3 pré-candidatos (Cabo Daciolo, Clariana Barão, Rui Costa Pimenta); 8 descontinuados.

    Reference

    • Rui Costa Pimenta (PCO) — mantido pre-candidate, contrariando a imprensa. Sete veículos (Estadão, Terra, DW, Bloomberg Línea, banzeironews, ohoje, clicrdc) o listaram como "já oficializado", mas sempre dentro de listas agregadas, sem relato datado da convenção. A fonte primária do próprio partido (Diário Causa Operária) o trata como pré-candidato e marca o lançamento nacional da chapa — com Antônio Carlos Silva na vice — para 08/08/2026, às 10h, na Casa de Portugal (Av. da Liberdade, 602, SP); a escolha se deu na 38ª Conferência Nacional, instância interna, não convenção eleitoral. Todas as demais promoções deste painel têm data e local de convenção; esta não tem. ⚠️ Lista agregada de imprensa não é evidência de oficialização — é a mesma classe de fonte que produziu "Vera Lúcia" como vice do PSTU (4.11.9), "Clariana Brandão" na Veja e "Edmilson Dias" no G1.
    • Clariana Barão (DC) — segue pre-candidate. O clicrdc de 04/08 afirma expressamente que "Clariana Barão (DC) ainda é pré-candidata"; não há registro de convenção do DC.
    • Cabo Daciolo (Mobiliza) — segue pre-candidate. Só há registro da pré-candidatura anunciada em abril/2026; nenhuma convenção localizada.
    • ⚠️ Lacuna de cobertura: dois candidatos oficializados estão fora do monitoramento. Leonardo Avalanche (PRTB) — convenção em Goiânia, 30/07/2026, chapa pura com a policial militar veterana Tenente Dalma na vice (relato datado do G1). Wilson Grassi Júnior (Democrata, ex-PMB) — oficializado, vice indefinido. Ambos aparecem nas listas de presidenciáveis de Estadão, DW, Bloomberg Línea e CNN. Incluí-los exige o outro procedimento (INSERT em candidates + CANDIDATE_PATTERNS/BRAVE_QUERIES em candidate_utils.py + retroactive_scan.py) — pendente de decisão. Custo baixo: os artigos já estão no banco, então o scan retroativo aproveitaria a cobertura existente.

  9. v4.11.10 2026-08-03 Alerta de coleta: separa fonte bloqueada de falha real

    Fixed

    • O contador "Erros" do alerta do Telegram não distinguia fonte indisponível de falha de pipeline. Era um grep -cE 'ERROR|ERRO' no log inteiro (run_coleta.sh), então um feed com HTTP 403 e uma etapa morta contavam igual. Pior: falha de etapa não-crítica não derruba o exit code do collect.py e portanto não cai no ramo "coleta falhou" — e ERRO ao gerar snapshot público (dashboard servindo dado velho) também era só mais um número. Um dia com o snapshot quebrado teria mandado exatamente o mesmo "Erros: 4" que um dia normal.
    • Agora são dois contadores: Fontes off (feed/sitemap indisponível — crônico e inofensivo) e Falhas (todo o resto). A separação ancora em -> ERRO, a assinatura de erro por fonte dentro do loop dos coletores (rss.py:85,164 · google_news.py:161,262 · sitemaps.py:223 · brave.py:239), o que cobre as quatro variantes de mensagem sem enumerá-las. Erro estrutural nunca leva a seta, então cai em Falhas por padrão — fail-safe: mensagem de erro nova conta como grave até prova em contrário. Header do alerta passa a ❌ coleta com FALHA quando Falhas > 0.

    Changed

    • "Novos" no alerta virou Artigos novos + Classificações. O número antigo vinha do Total novos: do relatório, que soma todas as etapas — inclusive classificação. Na coleta de 03/08 07:00, os "1973 novos" eram na verdade 221 artigos de coletor mais 1752 linhas de body/gênero/sentimento/tópicos (950 só de tópicos, efeito do backfill de 4.11.8). O alerta sugeria um volume de coleta ~9× maior que o real.
    • Feed do Blog do Zé Otávio atualizado para blogdozeotavio.com/feed/. O endereço antigo (blogdozeotavio.wordpress.com) foi fechado pelo autor e responde "Site privado" com HTTP 200 — falhava silenciosamente desde abril. Fonte de baixo volume (14 artigos desde 01/04), mas o feed novo responde íntegro.

    Reference

    • Fontes com bloqueio deliberado, mantidas como estão: Carta Capital (HTTP 403 com challenge do Cloudflare) e Jornal Opção (HTTP 403 no feed e no sitemap). Não são quebras a consertar — são bloqueios de bot. Cobertura preservada por outras rotas: Carta Capital entrou 62 vezes nos últimos 7 dias via Google News e sitemap; Jornal Opção, 391. O RSS direto é redundante nos dois casos. Contornar o bloqueio (User-Agent, headers) seria decisão editorial, não correção técnica.

  10. v4.11.9 2026-08-02 Três oficializações: Lula (PT), Hertz Dias (PSTU) e Edmilson Costa (PCB)

    Changed

    • Lula (PT) oficializado candidato à reeleição. Convenção nacional em 02/08/2026, no Expo Center Norte (SP), com Geraldo Alckmin (PSB) na vice. Coligação com PSB, PCdoB, PV, PDT, PSOL e Rede. É a sétima vez que disputa a Presidência. Fontes: Correio 24h, Poder360.
    • Hertz Dias (PSTU) oficializado candidato. Convenção em 31/07/2026, no Sindicato dos Metroviários (Belém, zona leste de SP), em chapa pura com a professora mineira Vanessa Portugal na vice. Fontes: Agência Brasil, O Tempo, Metrópoles.
    • Edmilson Costa (PCB) oficializado candidato. Convenção em 01/08/2026, na Câmara Municipal de SP, com a professora Cleusa Santos na vice. Fontes: Agência Brasil, Metrópoles, Correio Braziliense.
    • Bios atualizadas nos três registros com a data da convenção e o nome do vice.
    • 📝 Composição atual: 13 monitorados ativos — 8 candidatos (Lula, Flávio Bolsonaro, Ronaldo Caiado, Renan Santos, Samara Martins, Romeu Zema, Hertz Dias, Edmilson Costa) e 5 pré-candidatos (Michelle Bolsonaro, Augusto Cury, Cabo Daciolo, Rui Costa Pimenta, Clariana Barão); 7 descontinuados.

    Reference

    • Não alterados nesta rodada, em observação até o prazo legal (05/08):
      • Michelle Bolsonaro — aliadas (Bia Kicis, Celina Leão) anunciaram em 01/08 que ela disputará o Senado pelo DF, o que a tiraria da corrida presidencial. Mantida como pre-candidate: ela não declarou pessoalmente (esteve internada para exames de enxaqueca) e, segundo Valdemar Costa Neto, "o presidente vai decidir se ela é candidata ao Senado". A convenção do PL-DF ocorre em 02/08 às 17h, no Parque da Cidade. Precedente que recomenda cautela: ela já foi marcada dropped em 13/04/2026 por ida ao Senado e reativada em 13/05.
      • Clariana Barão — convenção nacional do DC estava prevista para 02/08, sem registro de realização até o fechamento desta entrada. Segue pre-candidate.

  11. v4.11.8 2026-07-31 Fix definitivo: tópicos por par (artigo, candidato) + backfill do backlog

    Fixed

    • topicos.py corrigido: pendência agora é checada por PAR (article_id, candidate), não por artigo. A query antiga (LEFT JOIN topics t ON a.id = t.article_id WHERE t.id IS NULL, via coluna legada singular articles.candidate) considerava um artigo "processado" assim que qualquer candidato ganhava tópicos — candidatos associados depois (retroactive scan, pattern novo casando) nunca eram cobertos. Extração via Gemini continua rodando uma vez por artigo (tópicos são propriedade do texto, o prompt já proíbe citar nome de candidato); pares pendentes de um artigo que já tem tópicos por outro candidato são preenchidos por cópia direta, sem custo de LLM, com filtro de auto-referência reaplicado pro candidato-alvo.
    • Filtro de auto-referência passa a ser dinâmico, carregado da tabela candidates (nome completo + primeiro/último nome), em vez de lista fixa hardcoded que cobria só 9 dos 20 candidatos do roster.
    • Backfill do backlog histórico rodado em produção (31/07/2026, manual, fora do cron): 26.000 pares pendentes em 16.434 artigos → 82.949 tópicos preenchidos, 0 chamadas ao Gemini, 0 erros. Só 1 par ficou pendente (article_id 15165 × leonardo-pericles) — artigo órfão pré-existente (linha em article_candidates sem articles correspondente, drift anterior a este fix, não causado por ele). Verificado: /comparativo e páginas de candidato renderizando tópicos completos, sem perda de performance (índice idx_topics_cand_art cobre a query mesmo com o volume novo).
    • Ver [[feedback_topicos_bug_par_vs_artigo]] pro achado original (30/07) e a análise que embasou o fix.

  12. v4.11.7 2026-07-30 Classificação retroativa: Clariana Barão + bug sistêmico de tópicos

    Fixed

    • Página de Clariana Barão passa a exibir sentimento e tópicos. Os 6 artigos pré-existentes na retroativa (25-29/07) estavam com verified=0, sem sentimento e sem tópicos — o pipeline normal só roda para pares novos coletados após o cadastro. Sentimento classificado via Gemini (6/6 positivo); tópicos reaproveitados por cópia direta dos pares co-citados no mesmo artigo (samara-martins/aldo-rebelo/joaquim-barbosa) sem chamada ao LLM — tópicos são propriedade do texto do artigo, não do candidato-alvo (o prompt de extração proíbe citar nome de candidato como tópico). verified=1 aplicado manualmente nos 6 (títulos inequívocos, mesmo critério do caso Joaquim Barbosa).
    • Bug sistêmico descoberto em topicos.py: tópicos são tratados como propriedade do artigo, não do par (article, candidate). A query de pendências (LEFT JOIN topics t ON a.id = t.article_id WHERE t.id IS NULL) usa a coluna legada singular articles.candidate em vez da tabela N:N article_candidates — um candidato associado retroativamente a um artigo que já tem tópicos (extraídos pro candidato original da coleta) nunca ganha tópicos próprios. Backlog medido: 25.846 pares sem tópicos em todo o banco, atingindo candidatos já oficializados (flavio-bolsonaro 8133, lula-silva 5765, ronaldo-caiado 2463, romeu-zema 2114, michelle-bolsonaro 1857, renan-santos 1213, entre outros 14). Não corrigido em produção — fix ingênuo faria a próxima coleta herdar as 25.846 pendências de uma vez (~5.170 chamadas em lote ao Gemini). Registrado para decisão futura.
    • Correção de um erro operacional na mesma sessão: um UPDATE verified=1 sem escopo de ID (destinado aos 6 pares aprovados) acabou atingindo 56 pares — a coleta das 21h já havia rodado e trazido 45 pares novos de Clariana nesse meio-tempo. Destes, 11 nunca tinham passado pelo verificador; ao rodar a checagem real (mesma lógica LLM de verificador.py), 5 eram falsos positivos genuínos (artigos sobre Aldo Rebelo/Caiado e Zema/Barbosa sem relação com Clariana) e foram removidos; os 6 restantes confirmados.

    Reference

    • Composição não muda nesta entrada (mantém 14 monitorados — 5 candidatos, 8 pré-candidatos, 7 descontinuados, conforme v4.11.6).