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 9 de 12 · 136 versões no total.
-
v3.9.2 2026-04-29 Candidato divisivo (clivagem editorial da semana) Added
- Bloco "Candidato divisivo" na coluna direita do bloco 2.3 (que estava vazia desde a remoção de "Evolução do sentimento" na v3.9.1). Aponta o pré-candidato com maior dispersão de sentimento entre veículos na semana corrente — sinal de polarização editorial. Métrica: desvio-padrão de
sentiment_scorepor candidato, threshold mínimo de 10 artigos classificados. - Citação de matérias extremas: o card mostra qual veículo + qual matéria ancoraram o lado mais crítico e o mais elogioso da cobertura, com link clicável (target=_blank, rel=noopener) e título truncado em 90 caracteres. Concretiza pra o leitor a clivagem editorial.
Changed
- Label "amplitude" → "dispersão": o número exibido (ex.: 0.55) é desvio-padrão, não range max-min. Termo anterior induzia a leitura errada — quem visse "amplitude 0.55" e o range "-1.00 ↔ +1.00" estranhava a aritmética.
- Range concreto adicionado logo abaixo do label (
range -1.00 ↔ +1.00em monospace) — leitor casual aproveita a leitura intuitiva; leitor técnico aproveita o std.
Notes
- Critério estatístico (std) é mais robusto a outliers que range simples. Um único artigo extremo de cada lado já fixa range = 2.00, mesmo com 99% da cobertura neutra; std reflete a distribuição real.
- Card complementa o "Candidato destaque" da coluna esquerda: destaque captura movimento de volume; divisivo captura clivagem editorial. Duas leituras independentes da semana.
- Bloco "Candidato divisivo" na coluna direita do bloco 2.3 (que estava vazia desde a remoção de "Evolução do sentimento" na v3.9.1). Aponta o pré-candidato com maior dispersão de sentimento entre veículos na semana corrente — sinal de polarização editorial. Métrica: desvio-padrão de
-
v3.9.1 2026-04-29 Refinamento da Cenário Semanal Added
- Dumbbell de volume por candidato (seção 2.4): visualização semana corrente × semana anterior. Bolinha cinza no valor da semana passada, bolinha colorida (cor do candidato) na semana atual; linha verde aponta crescimento, vermelha aponta queda. Resolve a comparação cruzada entre candidatos sem o ruído de uma timeline (descartada por excesso de séries).
Changed
- Reordenação de blocos da Cenário Semanal: Sentimento (destaque + por candidato) agora vem antes de Tópicos emergentes — leitura imediata do clima da semana, com aprofundamento em pauta logo depois.
- Critério do Candidato destaque migrado para compósito
growth × log1p(volume)(mesma fórmula dos tópicos emergentes). Antes era|Δ| absoluto— capturava também colapsos. Novo critério filtrascore > 0: destaque é sempre editorial positivo. Quando ninguém está em alta (caso comum nas primeiras horas de uma semana), o bloco mostra mensagem honesta. - KPI "Sentimento médio" ganhou detail com delta vs semana passada (
↑/→/↓ vs +X.XX). Card "Evolução do sentimento" do bloco 2.3 removido — era informação duplicada.
Fixed
app.pyregistrava paths antigos após a renumeraçãopages/N_*.pyda v3.9.0.st.navigationquebrava ao tentar montar páginas — HTTP 200 do Streamlit não detectava (a app sobe; o erro só dispara ao trocar de página). Mapa_REDIRe lista dest.Page(...)atualizados.- KPI "Candidatos cobertos" (Cenário Semanal) contava
nunique()emarticle_candidatesda semana sem filtrardropped. Resultado: 14 vs 12 mostrados no grid (4 dropped tinham vínculos históricos contando dobrado). Agora segue o mesmo critério do grid (pre-candidate + candidatepor padrão; sócandidatequandoonly_confirmed=True).
Notes
- Janela do Cenário Semanal continua segunda-domingo. No meio da semana, o dumbbell e o destaque mostram comparação parcial (3 dias da semana corrente × 7 da anterior) — esperado.
- Removido um falso positivo manualmente do banco em 29/04: artigo "Datafolha divulga 1ª pesquisa de opinião após registro de candidaturas" (Agência Brasil), vinculado erroneamente a Cabo Daciolo. Conteúdo era de eleição passada com
published_atfalsamente atualizado pela republicação. Verificador critério 6 não pegou — vale revisar regras de período eleitoral consumado se virar recorrente.
-
v3.9.0 2026-04-29 Cenário Geral × Cenário Semanal: split editorial Added
- Nova página: Cenário Semanal. Janela fixa segunda-domingo da semana corrente, sem filtro de período. Conteúdo: KPIs da semana (volume + Δ vs anterior, candidatos cobertos, fontes únicas, sentimento médio), grid de pré-candidatos com volume e sentimento da semana + delta, tópicos emergentes, candidato destaque, evolução do sentimento, sentimento por candidato (grid horizontal), lista de artigos publicados na semana.
Changed
- Cenário Geral refocada para visão histórica: removidas seções de "Esta Semana", "Tópicos emergentes desta semana", "Candidato destaque", "Sentimento da semana" e "Sentimento por candidato" (semanais) — todas migradas para Cenário Semanal.
- Pills de período saíram da sidebar. Agora vivem inline no body de Cenário Geral (única página com janela ajustável). Default:
Tudo(toda a série desde 25/03/2026). Outras opções:90 dias,30 dias,7 dias,Personalizado. Cenário Semanal e demais páginas usam janela fixa por desenho. - Ordem do menu: Início → Cenário Geral → Cenário Semanal → Pré-candidatos → Comparativo → Radar → Espectro Editorial → Zeitgeist → Análises → Metodologia → Changelog. Arquivos
pages/N_*.pyrenumerados em cascata. - Grid de pré-candidatos imediatamente após os KPIs em ambas as páginas (geral com volume total no período; semanal com volume da semana + delta vs anterior).
Notes
- Janela do Cenário Semanal é segunda-domingo (semana civil corrente). Não confundir com a janela do resumo semanal editorial (sábado-sexta, publicado no sábado seguinte) — janelas diferentes para usos diferentes.
boot()ganhou parâmetrosdays_backedate_rangepara que cada página controle sua própria janela; sidebar ficou só com brand + toggle "apenas confirmados" + tema.
-
v3.8.2 2026-04-29 Recorte do dashboard agora é editorial, não de coleta Fixed
- Timeline de cobertura escondia silenciosamente artigos válidos do início da série.
load_data()filtrava porfetched_at >= now() - 30d. Como o coletor entrou em produção em 25/03 capturando publicações retroativas, 871 artigos publicados entre 25-30/03 ficavam fora do dashboard — e o problema piorava 1 dia por dia (cada amanhã, mais 1 dia da janela editorial sumia do gráfico). - Filtro passa a ser por
published_atcom cutoff sempre limitado porMIN_PUBLISHED_DATE = 2026-03-25(recorte oficial). Janela "30 dias" agora significa "publicado nos últimos 30 dias", não "coletado nos últimos 30 dias". - Período "Personalizado" migrado de
fetched_atparapublished_at(comparse_published_datespara lidar com formato misto com/sem timezone —pd.to_datetimedireto gera NaT silenciosamente, conforme gotcha já documentado).
Notes
- Mudança afeta arquivos:
src/core/data.py(queries SQL) esrc/core/bootstrap.py(recorte personalizado). - Cache
@st.cache_data(ttl=300)é invalidado no restart doeleicoes-dashboard.service.
- Timeline de cobertura escondia silenciosamente artigos válidos do início da série.
-
v3.8.1 2026-04-28 Leonardo Péricles dropped Changed
- Leonardo Péricles (UP) marcado como
status='dropped'no banco — substituído por Samara Martins como pré-candidato da Unidade Popular em 08/04/2026. A descoberta veio da análise do resumo mensal de abril (apenas 24 artigos sobre Péricles vs 108 sobre Samara). Status alterado retroativamente em 28/04/2026 para refletir a transição partidária. - Coletores Brave/Google News/Tavily passam a ignorar Péricles automaticamente (registros históricos preservados no banco).
- README atualizado: Péricles movido para "Descontinuados".
- Leonardo Péricles (UP) marcado como
-
v3.8.0 2026-04-28 Resumo Mensal eleitoral: novo produto editorial Added
- Resumo Mensal de Eleições 2026 — espelha a arquitetura do resumo semanal (Opus 4.7 + extended thinking + ordem das seções por volume), mas com fôlego de balanço — 1500–2000 palavras, identificando tendências consolidadas ao longo do mês, viradas de narrativa e comparações com o mês anterior quando os dados sustentam.
- Janela editorial: dia 26 do mês anterior ao dia 25 do mês alvo. O ciclo fecha no dia 25; draft sai na manhã do dia 26.
- Cron:
monthly-summary.timerna LXC-121 dispara dia 26 de cada mês às 08h00 (BRT). Próximo disparo automático: 26/05/2026. - Tag dedicada:
resumo-mensal(separada deresumo-semanal). - Suporte a catch-up retroativo via flag
--month YYYY-MM. "Resumo de abril de 2026" (cobertura completa do primeiro mês desde 25/03/2026) gerado manualmente em 28/04/2026. - Página Metodologia do dashboard: seção "Resumos editoriais — produtos associados" reescrita pra cobrir as duas séries (semanal + mensal).
Changed
- Streaming obrigatório no SDK Anthropic — chamadas com extended thinking (12K) + max_tokens 28K + prompt grande passam de 10min e exigem
client.messages.stream(). Aplicado em ambosweekly_summary.pyemonthly_summary.py(preventivo no semanal antes de 02/05).
Notes
- O resumo mensal vive no projeto
blog-automation(/opt/blog-automation/produtores/monthly_summary.pyna LXC-121), não noeleicoes2026. Esta entrada documenta a mudança aqui porque o produto editorial é parte do ecossistema visível e consome dados deste banco.
-
v3.7.3 2026-04-28 Resumo Semanal eleitoral: Opus 4.7 + ordem dinâmica por volume Changed
- Modelo editorial do resumo semanal: Claude Opus 4.7 (primário) com extended thinking (
budget_tokens=12000). Cadeia de fallback: Opus 4.7 → Opus 4.6 → Sonnet 4.6 → Haiku 4.5 — todos com thinking habilitado. Antes: Opus 4.6 sem thinking, com fallbacks Sonnet 4.6 → Haiku 4.5. - Ordem das seções do post: agora dinâmica, baseada no volume de menções da semana (decrescente). O pré-candidato com mais artigos publicados abre a análise; os demais aparecem em sequência. Antes: hierarquia fixa Lula → Flávio → Tarcísio → demais.
max_tokens: 8000 → 28000 (16K saída visível + 12K thinking).- Página Metodologia do dashboard: nova seção "Resumo semanal — produto editorial associado" descrevendo cron, modelo, ordem, continuidade narrativa e revisão humana.
Fixed
- Bug latente em
generate_image_prompt— função liadata[c]['total_articles']mas o campo nunca era preenchido emfetch_articles_data. Resultado: o prompt de imagem sempre caía no fallback genérico ("Two or three bold geometric shapes"), independentemente do número de candidatos ativos na semana. Agoratotal_articlesé gravado por candidato (soma das contagens de sentimento) e a paleta/composição da imagem reflete o volume real.
Notes
- O resumo semanal vive no projeto
blog-automation(/opt/blog-automation/produtores/weekly_summary.pyna LXC-121), não noeleicoes2026. Esta entrada documenta a mudança aqui porque o produto editorial é parte do ecossistema visível e consome dados deste banco. - Próximo resumo com a nova configuração: sábado 02/05/2026.
- Modelo editorial do resumo semanal: Claude Opus 4.7 (primário) com extended thinking (
-
v3.7.2 2026-04-27 Upgrade de modelo e verificador anti-FP mais rigoroso Changed
- Modelo de IA: todos os produtores (sentimento, tópicos, verificador, gênero, Zeitgeist) migram de
gemini-2.5-flash-liteparagemini-3.1-flash-lite-previewviaGEMINI_MODELemsrc/gemini_client.py. - Verificador anti-FP: novo critério 6 — artigos sobre ciclos eleitorais anteriores (2014, 2018, 2022) sem gancho em 2026 são removidos. Corrige falsos positivos históricos indexados pelos buscadores.
- Modelo de IA: todos os produtores (sentimento, tópicos, verificador, gênero, Zeitgeist) migram de
-
v3.7.0 2026-04-21 Zeitgeist: 6ª dimensão analítica Added
- Nova página Zeitgeist — entre "Espectro Editorial" e "Análises" no menu. Mede a aderência do debate eleitoral a seis agendas globais estruturais: clima, transição energética, inteligência artificial, geopolítica, biodiversidade e crise da democracia.
- Produtor
src/produtores/zeitgeist.py— classificador multi-rótulo por artigo via Gemini 2.5 Flash Lite com JSON Schema enforced. Threshold de aderênciaconfidence ≥ 0.5; evidência é trecho literal do texto para auditoria. - Schema:
- Tabela
article_zeitgeist(article_id, cluster, confidence, evidence, created_at)— N:M, com CHECK constraint nos 6 clusters canônicos. - Tabela
article_zeitgeist_processed(article_id, processed_at)— distingue "ainda não classificado" de "classificado sem aderência" (a maioria dos artigos).
- Tabela
- Pipeline incremental —
run_coleta.shagora rodaprodutores/zeitgeist.pydepois do verificador. Só processa artigos ainda não classificados. - Visualizações na página:
- KPIs globais (artigos classificados, com aderência, cluster dominante, total de vínculos).
- Bar chart horizontal de volume por cluster.
- Ranking de aderência global por pré-candidato (% dos artigos que tocam agenda global).
- Heatmap Candidato × Cluster (composição temática individual).
- Linha temporal semanal por cluster.
- Heatmap Cluster × Espectro Editorial.
- Expander com amostras aleatórias de evidências por cluster.
- Classificação retroativa de todo o corpus (~10 mil artigos) feita em 21/04/2026.
Rationale
Material central dos capítulos 4 ("A corrida pelo enquadramento") e 9 ("O que a máquina viu") do livro A Lente e o Espelho. A implementação com volume atual (baixo) evita reprocessamento caro em setembro/2026 quando o corpus estará várias vezes maior.
Notes
- "Democracia" tem escopo estrito: só erosão institucional, desinformação sistêmica, regulação de plataformas e ataques ao STF/TSE — não cobre rejeição/aprovação presidencial ou disputas comuns entre candidatos.
- "IA" exclui menções a ferramentas editoriais da redação ("LE.IA do Estadão", resumos gerados por IA) — só conta IA como agenda política/social.
- "Geopolítica" não é ativada automaticamente por declaração política em solo estrangeiro; o conteúdo precisa desenvolver relações internacionais substantivamente.
- A maioria dos artigos retorna lista vazia de clusters — é o comportamento desenhado.
-
v3.6.0 2026-04-20 Gênero jornalístico no dashboard + reordenação do Cenário Geral Added
- Seção "Gênero jornalístico" na página Espectro Editorial — combina três blocos:
- Filtro por gênero (multiselect) que afeta todos os gráficos de espectro abaixo. Permite perguntas como "de que espectro vêm as opiniões sobre X?" ou "como análises se distribuem entre veículos?".
- Distribuição global de gêneros — bar chart horizontal com o volume de artigos por categoria (Notícia, Análise, Opinião, Entrevista).
- Cruzamento Gênero × Espectro editorial — heatmap com contagem absoluta de artigos em cada combinação (genre × editorial_lean).
- Os dados de
articles.genrejá vinham sendo coletados pelo produtorprodutores/genero.py(Gemini 2.5 Flash Lite), mas não tinham UI dedicada.
Changed
- Cenário Geral — reordenamento de seções:
- "Pré-candidatos monitorados" (grid de cards) agora aparece logo depois dos KPIs globais, antes da Timeline de cobertura. Dá contexto quantitativo por candidato antes do gráfico temporal.
- "Exportar artigos (CSV)" movido para depois da Timeline de cobertura. O botão sai do alto da página e fica próximo aos dados que o leitor acabou de visualizar.
Reason
articles.genre(4 classes) era o único sinal de classificação estruturada sem representação no dashboard. O filtro em Espectro Editorial é a integração mais útil: cruza gênero com viés editorial e permite recortes analíticos novos.- O grid de pré-candidatos funcionava como um "sumário visual" escondido abaixo da Timeline. Subindo-o, a página abre com os números por candidato em primeiro plano.
Fixed
- Margens dos gráficos de gênero (patch pós-deploy) — bar chart de distribuição e heatmap Gênero × Espectro estavam cortando os rótulos dos eixos ("Notícia/Análise/Opinião/Entrevista" e "Esquerda/Centro/Direita"). Margem esquerda aumentada para 90px e títulos redundantes dos eixos removidos.
- Seção "Gênero jornalístico" na página Espectro Editorial — combina três blocos:
-
v3.5.3 2026-04-20 Limpeza de UI: Sobre vira seção de Metodologia, Análises vira página própria Changed
- Página "Sobre" mesclada no topo de "Metodologia" — descrição do painel, disclaimer de imparcialidade e guia de navegação agora abrem a página Metodologia. Remove duplicação e encurta o menu.
- Análises vira página independente — o feed de matérias SapiensLabs saiu de Metodologia e virou entrada própria no menu, entre Espectro Editorial e Metodologia.
- Exportar CSV reposicionado — botão de download agora aparece logo após os KPIs globais (antes ficava depois dos tópicos emergentes).
- Mapa de tópicos (treemap) limitado a top 25 — mantido o mínimo de 5 menções. Reduz ruído visual da cauda longa.
- Dropdown de Pré-candidatos ordenado por menções (desc) — antes alfabético; agora os candidatos mais discutidos aparecem no topo.
- Agenda de coleta corrigida na UI — KPI "Última coleta" e Metodologia passam a exibir 07h, 14h e 21h (BRT), refletindo o timer configurado na v3.4.2.
Removed
- Banner de disclaimer no topo do Cenário Geral ("Monitoramento automatizado — não é pesquisa eleitoral"). O mesmo texto permanece na Metodologia, agora a primeira coisa que o leitor encontra ao abrir a página.
- Link "Ver mapa completo de tópicos →" após os tópicos emergentes. Âncora desnecessária — o treemap está a uma rolagem de distância.
- Função
page_sobre()removida do código; rota?page=Sobreredireciona para Metodologia.
Reason
- Encurtar o menu lateral e reduzir duplicação entre "Sobre" e "Metodologia" — o leitor que buscava transparência metodológica já caía em Metodologia, e o disclaimer editorial aparece agora no topo dessa mesma página.
- Separar Análises em página própria dá destaque ao feed e evita enterrá-lo dentro da metodologia.
- Treemap cheio de 100+ tópicos fragmentava a leitura. 25 já cobre >80% do volume.
-
v3.5.2 2026-04-20 Cenário Geral: tópicos emergentes e treemap Added
- Destaque da semana — o tópico emergente com maior score agora aparece visualmente destacado (card com borda âmbar e fundo tintado) antes dos demais na lista.
- Grid de tópicos emergentes — ao invés de lista vertical, os 7 tópicos da semana aparecem em grid de 4 colunas horizontais, logo após a Timeline de cobertura.
- Mapa de tópicos (treemap) — nova seção no Cenário Geral com treemap de todos os tópicos com 5+ menções desde o início da coleta. Área proporcional ao volume; coloração por densidade.
Changed
- Posição dos tópicos emergentes — movidos para imediatamente após a Timeline de cobertura (antes ficavam abaixo do heatmap candidato × semana).
- Evolução de tópicos — volta a ser full-width, sem competir com os emergentes em layout de colunas.
Reason
- Tópicos emergentes são o sinal editorial mais imediato — faz sentido aparecer logo depois do contexto temporal que a timeline oferece.
- O treemap resolve a pergunta "quais são os tópicos?" de forma visualmente direta, mostrando de uma vez a concentração nos 4 dominantes e a cauda longa.