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 1 de 12 · 136 versões no total.

  1. v4.55.0 2026-09-13 A API pública discordava do painel em 526 artigos

    Adicionado

    • total_articles_imprensa e articles_today_imprensa no /api/v1/stats. Passam a existir os pares que faltavam: os campos sem sufixo continuam sendo o acervo bruto — o tamanho da coleta — e os _imprensa são a medida de cobertura, a mesma que o painel exibe. Quem cita "quantos artigos" usa os segundos. A nota do meta explica a diferença em vez de deixar o leitor descobrir sozinho.

    Corrigido

    • A API dizia 78.537 artigos enquanto a home dizia 78.011. /api/v1/stats lia a tabela articles crua, com os porta-vozes (partidário, sindical, movimento) e os oficiais que a regra da casa exclui da cobertura de imprensa desde 02/09. São 526 artigos de diferença, e o painel passou nove dias discordando de si mesmo. O curioso é que o problema já tinha sido visto: em 04/09 ele foi corrigido no mesmo arquivo, mas só para as fontes — nasceu ali o total_sources_imprensa, e os artigos ficaram para trás.
    • O resto da API v1 agora lê a mesma coisa que as páginas. Não era só o stats: as fontes que cobrem cada candidato, as séries de sentimento e de tópicos, a listagem de artigos e a ficha por id liam o acervo bruto, enquanto as páginas equivalentes leem a view. Dezesseis consultas ao todo. Ficam deliberadamente brutas apenas as três contagens do stats que existem para dizer o tamanho da coleta, e agora estão marcadas como tal no código.
    • A página /api chamava de total_articles um número que era de imprensa. O valor exibido sempre veio da home, correto; o nome da variável é que apontava para o campo errado da API — e o rótulo dizia só "artigos". Nome, valor e rótulo agora concordam.
    • O hero de sapienslabs.com.br/eleicoes-2026 mostrava 78.652 artigos e 1.968 veículos. O script que sincroniza esses números todo dia contava o acervo bruto — e, no caso dos artigos, sem sequer aplicar o recorte de 25/03, apesar de o rótulo dizer "desde 25/03/2026"; o dos veículos dizia "imprensa BR" contando partidários e oficiais. Uma terceira régua, portanto, na página que apresenta o projeto. Corrigido para a régua do painel: 78.011 e 1.909. Os rótulos agora descrevem o que de fato é contado ("Artigos de imprensa", "Veículos · de imprensa, no Brasil"). O detalhe que torna isso urgente: é neste mesmo blog que sai a série *18 respostas sobre a imprensa*, e a página e os textos diriam números diferentes sobre a mesma coisa.
    • O teste-guarda não olhava a API. tests/test_articles_imprensa.py varria uma lista de arquivos escrita antes de app/api/v1.py existir; passava em verde sobre o arquivo onde o bug morava. Agora varre app/ inteiro por descoberta, com exceções explícitas: arquivo novo nasce coberto, e sair da cobertura exige um gesto que aparece no diff. Entrou também o scripts/update_site_stats.py, pela mesma razão — mora fora de app/, mas apresenta número em página pública. Somam-se dois testes que prendem a simetria — contagem bruta sem par de imprensa reprova, e par que não leia a view reprova.

  2. v4.54.1 2026-09-12 Todo domingo sumia do gráfico semanal

    Adicionado

    • O seletor de período sabe dizer quais janelas o arquivo cobre. Aqui a guarda não dispara: a série começa em 25/03 e a maior janela do seletor são 90 dias. Ela entra porque o motor é transplantado entre os painéis, e guarda que existe só num deles é exatamente a que se perde na cópia seguinte — foi o que aconteceu com o selo de novidade, que nasceu aqui e desembarcou no monitor do STF sem a pergunta "há passado para comparar?". No irmão, com sete dias de acervo, a marcação acusa três dos seis botões.

    Corrigido

    • A semana do Zeitgeist não engole mais o domingo. "Evolução semanal por cluster" calculava o início da semana com '-' || (strftime('%w', d) - 1) || ' days'. No domingo %w é 0, a conta dá −1 e o modificador sai como '--1 days' — inválido. O SQLite não reclama: devolve NULL. O resultado é que todo domingo desaparecia da série, calado, desde que o gráfico existe. Medido no acervo antes de corrigir: **1.220 artigos publicados em domingos e 1.428 pares artigo×cluster caindo em NULL**; com a expressão nova, zero. O cálculo virou a função sql_semana(), com a explicação do defeito junto, e ganhou cinco testes — inclusive o que prende o erro mais provável de quem for consertar por conta própria: jogar o domingo para a semana seguinte em vez da anterior. O mesmo defeito e a mesma correção foram para o stf-monitor.

  3. v4.54.0 2026-09-12 O painel se cala quando não tem passado; a rubrica das entidades ganha quatro regras

    Corrigido

    • Nenhuma régua comparativa aparece sem arquivo que a sustente. "NOVO" e "N×" dizem que um assunto não existia no período anterior — afirmação que vira mentira quando o banco simplesmente começa depois do início daquela janela. O caso apareceu no painel irmão do STF, que tem seis dias de acervo e por isso marcava os cinco temas em alta como novos, incluindo um inquérito que corre desde 2019: o selo descrevia a idade da coleta, não o noticiário. tem_base_de_comparacao() agora compara o começo do arquivo com o início da janela anterior; sem cobertura, o selo some, a lista passa a ser ordenada por volume, o título vira "Os temas do período" e a legenda diz o que a lista realmente mostra. No Eleições a guarda nunca dispara hoje (o acervo cobre desde 25/03), e é exatamente por isso que ela entra: a janela mensal quebraria se algum dia recuasse para antes disso. Seis testes novos, quatro puros e dois que renderizam o partial. O mesmo código foi para o stf-monitor.
    • O detalhe da entidade não é mais decepado no meio da palavra. O teto de 40 caracteres cortava "chapa de Romeu Zema (Novo)" em "chapa de Romeu Zema (No" — e o painel passava a informar que o governador de Minas comanda um estado chamado "No". O teto subiu para 60 e o corte passou a respeitar a fronteira de palavra (corta_detalhe), aparando pontuação órfã. Os 718 artigos cujos vínculos tinham sido truncados foram reprocessados com trilha de auditoria: 4.946 vínculos reescritos, zero falhas. A limpeza cega foi descartada no caminho — aplicar o corte novo sobre um texto já truncado apagaria "Master" de "Banco Master" sem ter como saber.
    • A coluna grafia guarda o que a matéria escreveu, não o nome normalizado. Ela existe para registrar como cada veículo se refere à pessoa, e estava recebendo uma cópia do nome canônico — o dado que ela deveria preservar se perdia na gravação. Quando o modelo não devolve grafia, o campo fica nulo em vez de copiar o nome.

    Alterado

    • Rubrica de entidades v1.2 — quatro decisões editoriais. Candidato a vice é candidato, com "vice" no detalhe, nunca herdando o papel do titular. "Ex-candidato" saiu: quem nunca teve candidatura oficializada não é ex-nada, e volta a ser descrito pela profissão ou pelo cargo — ou "pré-candidato", o termo que a casa usava antes do registro. Senador que disputa a Presidência é senador ou candidato conforme o assunto da matéria, porque as duas descrições são verdadeiras e a precisão está no contexto. E parentesco só entra quando o texto o afirma: 25 vínculos descreviam Michelle Bolsonaro como esposa de Flávio, erro que a versão anterior deixava passar. "Ex-primeira-dama" fica, por decisão do editor — é o termo da imprensa e um lugar real na política brasileira.
    • Rubrica v1.3 — grafia e apelido. O prompt ganhou seção própria para a grafia (devolver o trecho como está na matéria) e a regra do apelido: "Lulinha" não vira um nome completo inventado. Um erro de nome que aparecia no painel era do veículo; outro o modelo tinha construído sozinho a partir do apelido.
    • 33 fusões de alias curadas, com as cinco armadilhas preservadas: homônimos e quase-homônimos que pareciam a mesma pessoa e não são ficaram registrados no cabeçalho da tabela, para ninguém refazer a fusão por engano no futuro.

    Adicionado

    • A passada de entidades entra no run_coleta.sh, depois da de acontecimento, com teto de 400 artigos por rodada e sem ceder a vez (já está dentro da coleta). Provada em produção: 71 artigos, 461 entidades, 1,9 minuto.
    • Gabarito de 60 casos em docs/serie/apuracao/gabarito-entidades.csv, com coluna humana e nota: 51 acertos, 85%. As divergências foram de classificação, não de invenção — nenhuma pessoa extraída deixou de existir no texto. O verbete "Entidades" da página de método carrega o carimbo da aferição e as quatro regras.

  4. v4.53.1 2026-09-12 As análises descem para depois do dado

    Alterado

    • "Análises da série" sai da segunda posição da home e vai para a quarta, logo depois de "Os últimos dias na cobertura" (decisão do editor, 12/09 de madrugada). A seção abria a página antes de qualquer número: o leitor recebia a leitura editorial da casa antes da evidência que a sustenta, e a arte do bloco principal ocupava a primeira dobra inteira no celular. A ordem agora é o assunto que domina → a curva dos últimos dias → o que escrevemos sobre isso → manchetes extremas → cobertura crua. A seção continua acima do rodapé porque é o único caminho da home para o blog. Só o {% include %} mudou de lugar; o partial e o feed estão intactos.

  5. v4.53.0 2026-09-12 A série passa a 18 peças; passada de acontecimento aprovada

    Alterado

    • A série vira "18 respostas sobre a imprensa" (decisão do editor, 11/09 à noite). Entrou a peça 16, "Quem a imprensa escolhe para explicar" (30/09) — quem a imprensa chama para interpretar a disputa, quantos analistas, de que instituições e com que concentração. Ela nasceu de uma pergunta sobre a passada de entidades e é irmã da 15: as duas saem da mesma classificação, uma é a rede de quem faz a política, a outra a lista de quem a explica. Os planos de governo passaram para 01/10 e o fecho para 02/10, dois dias antes do primeiro turno. O total também deixa de ser 17, que é o número histórico de um dos candidatos. config/serie_calendario.json é a fonte única: a página de método, o lembrete de véspera e o pacote de apuração leem dali.
    • O verbete "Entidades" da página de método diz agora que a passada registra tanto quem faz a política quanto quem a imprensa chama para explicá-la, com papel de lista fechada; ficam de fora o que não é pessoa e quem assina a matéria.
    • Teste do lembrete de véspera reescrito. Ele afirmava títulos provisórios e ficava vermelho a cada revisão editorial (aconteceu em 11/09). A mecânica da mensagem passou a ser testada contra um calendário sintético; do calendário real só se afirma o que não pode mudar — dias seguidos, numeração contígua, pauta de trabalho única, nada em branco e o número do nome batendo com o de respostas.

    Adicionado

    • Gabarito da passada de acontecimento: 55/60 = 91,7%, aprovado (piso 80%). O rótulo do acervo fechou com 77.557 artigos e 34.950 acontecimentos, sem faltantes, em 4h35, cedendo a vez à coleta. Julgamento linha a linha em docs/serie/apuracao/gabarito-acontecimento.csv; análise das cinco divergências no rodapé de docs/serie/acontecimento-rubrica.md.
  6. v4.52.1 2026-09-11 Links de texto visíveis na prosa

    Corrigido

    • Link dentro de texto corrido aparecia como texto comum (achado do editor na página de método da série: "Candidatos" no verbete "Os 13" tinha link e ninguém veria). O reset global de <a> do painel, feito para a navegação e os cards, apagava cor e sublinhado também na prosa. A prosa, as ledes de hero e de seção passam a usar o token --link do DS 1.7.0 (par dark/light com contraste AA) com sublinhado, como o tema do blog já fazia. A cópia local do DS ganhou a camada de prosa do 1.7.0 (--link, --link-visited, --prose-*), que faltava.
  7. v4.52.0 2026-09-11 Método e glossário da série; acontecimentos na metodologia

    Adicionado

    • /metodologia/serie: a página de método e glossário da série "17 respostas sobre a imprensa" (decisão do editor, 02/09: uma página, extensão da metodologia, com âncora por verbete). Como cada peça nasce (apuração na véspera, escrita em sessão, um gráfico por peça, CC BY 4.0), o que os números medem e não medem, a programação lida do calendário da série e 27 verbetes com endereço próprio (declaratório, escada de voz, espectro, rajada, tapete…). É o link fixo da caixa "Como este texto foi feito". A metodologia principal ganhou ids nas seções e o link para a série; a página entra no sitemap.
    • Seção "Acontecimentos — o que aconteceu, não o assunto" na metodologia: a passada que nomeia acontecimentos a partir das rajadas por tópico e rotula cada matéria pelo fato de que trata; rubrica versionada no código.
  8. v4.51.0 2026-09-08 Análises da série com três posts; a extra dispara no fim da rodada

    Mudado

    • "Análises da série", na home, passa a mostrar os três posts mais recentes (decisão do editor, 08/09, no dia da primeira edição extraordinária): o mais recente à esquerda, como o card de sempre, com imagem e excerpt; os dois seguintes à direita, em cards compactos com imagem, etiqueta, data e título, sem excerpt. A etiqueta diz o tipo, Resumo semanal, Balanço mensal ou Extra, lida das tags do post no blog. No celular, coluna única.

    Corrigido

    • A edição extraordinária não se perde mais quando a coleta das 21h fecha depois das 22:30. O produtor era disparado por um horário fixo, e em 08/09 a primeira extra armada ("polícia federal", 113 matérias, 23 vezes a média do tópico) ficou sem texto porque o gatilho armou às 22:37; saiu com disparo manual. Agora a própria rodada dispara o produtor assim que fecha, e o horário fixo vira rede de segurança.
  9. v4.50.1 2026-09-04 Espelhos fora do índice; títulos de busca; o perfil do host vence o rótulo velho

    Mudado

    • Páginas-espelho de matéria (/cobertura/…) recebem noindex,follow. Elas já apontavam o canonical para o veículo, mas o Google seguia ranqueando 960 delas: 225 dos 278 cliques do painel em três meses (Search Console) vinham de buscas pela manchete dos outros — 149 de uma só, um quiz. Decisão do editor: não competimos com o veículo na busca. Os links continuam sendo seguidos.
    • /candidatos e /panorama com título e descrição de busca: "Candidatos a presidente 2026: os 13 nomes e a cobertura de cada um", com os nomes no texto (o painel aparecia na posição 92 para essa busca), e "Cobertura da imprensa nas eleições 2026, dia a dia".
    • Todas as rotas usam a assinatura atual do TemplateResponse (request primeiro) — as antigas falhavam no Starlette 1.x dos testes.

    Corrigido

    • O perfil revisado do host passa a vencer qualquer rótulo anterior do artigo. O refresh só trocava rótulos vazios, "unknown" ou propostos; 905 artigos ficaram com o rótulo do mapa manual antigo mesmo depois de o editor aprovar outro para o host — Diário Carioca com 391 "centro" e perfil "esquerda", Tribuna do Sertão com 267 "centro" e perfil "sem posição declarada". A proveniência gravada espelha o status do perfil (manual ou aprovado).
  10. v4.50.0 2026-09-04 Um slug por veículo: canonização por host

    Mudado

    • canonical_source() olha primeiro o HOST da URL. O mesmo veículo entrava com o nome do feed ("Diário Carioca") e com o domínio do buscador ("diariocarioca.com") e virava dois veículos: 319 hosts assim no acervo. Agora host conhecido vira o slug canônico, host desconhecido vira o próprio host, e o nome só decide quando a URL é opaca (Google News, encurtadores). Os cinco coletores e o backfill passam a URL. Efeito colateral bom: 85 artigos da Folha que vinham pelo feed da UOL como uol voltam para folha-sp, e as chaves-domínio do dicionário do blog que estavam "mortas" desde 31/08 voltam a casar. API: muitos slugs informais mudam (nome → domínio); os canônicos não.
    • archive.ph, archive.is, archive.today e web.archive.org na lista negra da coleta (arquivador não é veículo — a matéria é de outro; um deles saiu como "veículo" em Fontes consultadas do mensal). Os 4 artigos existentes saem do acervo com cópia de segurança. TSE e TRE-SP aprovados como oficial: estavam como proposta da máquina e por isso ainda contavam como imprensa.
    • Fila de canonização de 01/09: SpaceMoney, Ponta Negra News, Banzeiro News e Vero Notícias ganham slug canônico; junto com os da lista abaixo, são os "12 veículos" que esperavam desde a revisão do semanal.
    • Doze slugs do topo da coleta viram dez veículos canônicos (src/source_normalize.py). A BBC aparecia em três nomes (bbc, bbc-brasil, bbc.com), O Tempo e CBN em dois (o-tempo/otempo.com.br, cbn/cbn.globo.com), e Band, O Dia, Rádio Itatiaia, Diário Carioca, Agora RN, Imirante, Tribuna do Agreste e o Pravda em português só existiam como slug informal, sem nome de exibição. A peça 11 (O eco) agrupa republicações por slug — slug partido vira dois veículos onde há um. Atenção, API: source= muda para esses veículos (bbcbbc-brasil, cbn.globo.comcbn, otempo.com.bro-tempo, band.com.brband, odia.ig.com.bro-dia, rádio-itatiaiaitatiaia, diário-cariocadiario-carioca, imirante.comimirante, portuguese.news-pravda.comnews-pravda); os slugs antigos deixam de existir no acervo após o backfill.
    • Content-Signal: search=yes, ai-input=yes, ai-train=yes no robots.txt do painel. Decisão do editor (04/09): o que é CC BY 4.0 não bloqueia IA, e a permissão fica explícita em vez de ausente. A política gerenciada do Cloudflare só escreve ai-train=no; foi desligada e o sinal nasce na origem, aqui e no blog (tema 2.6.91).
    • espectro.py --sync-slugs: ressincroniza source_profile.slugs com os slugs dos artigos, para a página dos veículos escolher o nome de exibição certo depois de uma canonização.

    Corrigido

    • BBC News Brasil é centro, e a rubrica passa a dizer por quê. O mapa manual tinha marcado bbc.com como internacional em 02/09; a entrada nunca chegou aos artigos (o refresh casa o mapa pelo nome bruto da fonte, "BBC Brasil"/"BBC", não pelo host), e em 04/09 o editor decidiu que ela estava errada: a BBC News Brasil é o braço editorial da BBC para o Brasil, redação brasileira, imprensa nacional. Regra na rubrica (v1.5): a redação brasileira de um grupo estrangeiro não é internacional; o rótulo fica para o serviço mundial. Os 466 artigos seguem centro; os 2 que tinham pegado internacional pelo host voltam a centro.
  11. v4.49.2 2026-09-04 Um selo só para o que foi revisado à mão

    Mudado

    • "Classificação manual" e "Aprovado em revisão" viram um rótulo só, "Aprovado em revisão", na página /veiculos, no CSV/JSON e na API (proveniencia = aprovado). Decisão do editor: "ter dois rótulos não acrescenta em muito e só gera dúvida". Para quem lê, os dois significam a mesma coisa — um editor leu o veículo e confirmou o rótulo. A origem (mapa do projeto ou proposta da máquina aprovada) segue registrada no banco, em source_profile.status, como rastro; as fontes e a justificativa da apuração continuam aparecendo quando existem.
  12. v4.49.1 2026-09-04 Rubrica da passada sem a frase contraditória; fontes de imprensa na API; Perguntar filtra por veículo

    Adicionado

    • total_sources_imprensa no /api/v1/stats. O total_sources conta hosts do acervo bruto (com partidários, sindicais, movimentos e oficiais) e um painel de terceiro o exibiu como "fontes" (2.342). O campo novo conta só veículos de imprensa, a métrica do painel; o antigo fica, documentado como bruto.
    • Perguntar: filtro de veículo em sentimento_por_veiculo e artigos, por nome ou trecho (sem acento, sem caixa): "como a Folha trata o Lula" traz a Folha mesmo fora do top 10, sem o piso de 3 artigos.

    Corrigido

    • O prompt da passada de espectro dizia, em extrema-direita, "inclui veículos de propaganda estatal estrangeira hostil à democracia brasileira". Desde a regra de precedência (03/09), veículo estrangeiro é internacional antes de qualquer eixo: a frase contradizia a rubrica pública e não existe no CLASSIFICACAO.md. Removida; rubrica da passada em v1.4. Nada já classificado muda.