尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Arquivo público das checagens dos debates do 2º turno de 2026
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Arquivo público das checagens que quatro agências (Aos Fatos, Estadão Verifica, g1 Fato ou Fake e Lupa) publicaram sobre os debates do 2º turno de 2026 entre Lula e Flávio Bolsonaro, na Band (18/10) e na Globo (23/10).
Um script lê a página de cobertura de cada agência a cada duas horas, grava as checagens em data/ e publica um site estático no GitHub Pages. Não há servidor nem banco de dados. O histórico do git é o registro de tudo o que mudou.
#NÃOÉBEMASSIM, FALTA CONTEXTO, é enganoso), e o site mostra todos numa escala comum de quatro faixas (verdadeiro, impreciso, falso, sem faixa). A tabela que põe cada rótulo numa faixa é pública, em config/bands.json. O rótulo original fica sem alteração nos dados (label) e aparece ao passar o mouse sobre o veredito.INSUSTENTÁVEL da Lupa, é inconclusivo do Estadão) ficam em "sem faixa", que aparece em todo placar, mesmo zerado.src/adapters/) são código comum, o mesmo para os dois candidatos.Precisa de Node 24 ou mais novo (.nvmrc fixa o 24) e do pnpm na versão de packageManager do package.json.
pnpm install
pnpm ingest
pnpm build
python3 -m http.server --directory dist 8000
pnpm ingest acessa as páginas das agências (precisa de rede), junta o que encontrou com o que já está em data/ e regrava checks.json, checks.csv e run-report.json. O cliente HTTP respeita o robots.txt de cada site e espera 5 segundos entre duas requisições ao mesmo domínio. Os detalhes de cada execução (status HTTP, SHA-256 de cada download, tempos, tentativas de arquivamento) vão para .cache/run-log.json, fora do git.
Com as variáveis de ambiente IA_S3_ACCESS e IA_S3_SECRET definidas (chaves do archive.org, veja a configuração do GitHub abaixo), o ingest também pede à Wayback Machine uma cópia de cada página que ainda não tem cópia verificada. Sem elas, só aproveita cópias que já existem.
pnpm build monta o site em dist/ a partir de site/, config/ e data/. O comando do Python serve a pasta em http://localhost:8000. Use um servidor em vez de abrir dist/index.html direto, porque o app.js é um módulo JavaScript e o Chrome não carrega módulos em file://.
Para ver todas as opções do ingest:
node src/ingest.ts --help
O modo offline lê as páginas de uma pasta em vez da rede e não arquiva nada. Serve para mexer nos leitores e no site sem acessar as agências. A pasta .cache/ precisa ter cada página salva como <id da fonte>.html. A fonte do Aos Fatos na Globo também precisa de aosfatos-globo-2026-10-23.json, a resposta da API Escriba. Os ids das fontes estão em config/debates.json.
.cache/ não vem no repositório, porque o projeto não redistribui o HTML das agências. Os arquivos esperados e seus SHA-256 estão em test/golden/fixtures.json. Este comando confere se os seus batem:
node test/golden/fetch-fixtures.ts
Ele só consegue baixar sozinho os arquivos fixados a partir de uma cópia da Wayback Machine. Os de hoje foram salvos direto das agências em 24/10/2026, então quem não tem a pasta precisa salvar as páginas à mão, com os nomes acima.
Para não misturar o resultado com os dados publicados, grave em outra pasta:
pnpm ingest --offline .cache --data-dir .cache/data
pnpm build --data-dir .cache/data
pnpm check:labels .cache/data/run-report.json
pnpm typecheck
pnpm lint
pnpm vitest run test/unit/normalize.test.ts
pnpm vitest run test/golden/g1.test.ts
pnpm vitest run test/e2e/site.test.ts
Rode os testes um arquivo por vez, como acima. Os testes golden usam as páginas de .cache/ e conferem a contagem de checagens e de rótulos de cada página. O teste e2e abre o site num Chromium de verdade, o de CHROMIUM_PATH (padrão /usr/bin/chromium). Se esse arquivo não existir, ele usa o Google Chrome instalado. No GitHub Actions, o workflow roda pnpm test:unit (só os testes unitários).
São os mesmos cinco passos do roteiro que o site oferece para colar numa IA, no botão "Como auditar". Dá para fazer à mão. O site também publica esse roteiro para um agente que receber só o endereço. /llms.txt é o índice, no formato proposto em https://llmstxt.org/. /auditoria.md repete os passos abaixo. /robots.txt deixa ler e recusa treino de modelo, porque as falas e os rótulos são das agências.
src/adapters e veja se algum trata Lula e Flávio Bolsonaro de forma diferente. O nome de quem falou só vira um candidato em src/pipeline/normalize.ts, pela lista de apelidos de config/candidates.json.config/bands.json) define a faixa só pela agência e pelo rótulo, e se alguma linha de data/checks.csv tem uma band diferente da que a tabela manda. A página "Metodologia" do site mostra, ao lado da tabela, quantas vezes cada rótulo aparece para cada candidato.missing_since preenchido, que são checagens que sumiram da página da agência.url) e confira se a fala, o candidato e o rótulo batem. Se a agência bloquear o acesso, use archive_url ou https://web.archive.org/web/<url>.history e missing_since do CSV, com a data em que foram detectadas.Uma IA que não consegue clonar o repositório pode usar endereços que devolvem texto puro: o CSV bruto em https://raw.githubusercontent.com/<dono>/<repo>/main/data/checks.csv, o histórico em https://api.github.com/repos/<dono>/<repo>/commits?path=data/checks.csv e o diff de cada commit em <repo>/commit/<sha>.diff. O roteiro do site já vem com esses endereços preenchidos.
O sha256 de cada registro é o hash da cópia arquivada, não da página ao vivo (g1 e Estadão mudam bytes a cada acesso, por causa de anúncios). O archive_url já é o endereço id_ da Wayback Machine, que devolve os bytes originais da página. A Wayback Machine entrega esse arquivo comprimido em gzip, e o hash é do conteúdo já descomprimido. Para conferir:
curl -s --compressed "<archive_url>" | sha256sum
Sem --compressed o hash sai diferente. Depois passe o arquivo pelo leitor indicado em adapter (<tipo>@<versão>), na versão do código daquele commit.
Achou um erro? Abra uma issue dizendo o id da checagem e o que está errado. Toda correção vira um commit público, com data.
A página "Comparar agências" (comparar.html) lê data/claim-groups.json, que junta as checagens de agências diferentes que avaliam a mesma alegação de um candidato no mesmo debate. Os grupos são propostos por agentes de IA e revisados à mão antes do commit. A curadoria não roda no workflow, só quando alguém a dispara.
Gere a entrada cega da rodada, com a data como nome:
pnpm claims:input --run 2026-10-24
O comando grava data/claim-curation/<data>/input.json só com o id de cada checagem, uma letra no lugar da agência, a fala e o trecho. Não sobrescreve uma rodada que já existe.
Rode a curadoria no Claude Code com o roteiro data/claim-curation/<data>/workflow.js (o da rodada anterior serve de ponto de partida): três curadores por debate, um juiz só onde eles discordam, um editor das frases e um revisor de neutralidade. A saída de cada um vai para a mesma pasta, como curator-<debate>-<n>.json, judge-<debate>.json, editor.json e review.json. O roteiro entra no mesmo commit.
Monte o arquivo de grupos:
pnpm claims:assemble
Sem argumento, usa a rodada mais recente. pnpm claims:assemble <data> escolhe outra. O comando falha se algum grupo quebrar uma regra, e o build também: checagem que não existe, debate ou candidato misturados, agência repetida, menos de duas checagens, checagem em dois grupos, frase vazia ou com mais de 120 caracteres.
Confira que o arquivo bate com as saídas commitadas:
pnpm check:claims
O comando refaz os grupos, sai com erro se data/claim-groups.json estiver diferente e lista cada mudança feita à mão, com o motivo. O workflow do GitHub roda essa conferência depois de check:labels.
Mudança à mão vai em data/claim-curation/<data>/manual.json, nunca direto no arquivo de grupos:
{
"edits": [
{
"from": ["92e3caa21ac1", "df250d7b4df0"],
"to": {
"records": ["5434697c0611", "92e3caa21ac1", "df250d7b4df0"],
"claim": "O governo Lula abriu 700 novos mercados"
},
"reason": "A checagem do g1 (5434697c0611) também avalia os 700 novos mercados; incluída na revisão do mantenedor em 2026-10-24."
}
]
}
from lista as checagens do grupo que sai (null para só criar um grupo), to traz as checagens e a frase do grupo que entra (null para só remover) e reason é obrigatório. As edições valem na ordem do arquivo, e o grupo criado assim fica com origem manual. Um from que não bate com nenhum grupo faz o claims:assemble falhar.
A página "Comparar agências" mostra, para cada agência, a distância dos vereditos dela para os das outras nas falas que duas ou mais checaram, e as checagens cujo rótulo, citação ou identificador mudou depois de publicadas. A conta está explicada em "Distância das outras agências", na página de metodologia.
pnpm lean
O comando lê data/ e imprime, por agência, os mesmos números, intervalos e frases que a página mostra sem filtro de debate, e a frase do topo.
A coleta de 24/10/2026 gravou como novas parte das checagens do Estadão Verifica sobre o debate da Globo. O script src/repair/estadao-2026-10-24.ts refez essa coleta com as regras atuais, e o relatório data/repairs/2026-10-24-estadao.json lista cada id juntado a um id mais antigo (merged), os que ficaram novos (new) e os que sumiram (missing).
Se as agências usam um formato de página que já tem leitor, não precisa mexer em código.
config/debates.json, acrescente um item em debates com id (por exemplo sbt-2028-10-20), broadcaster (nome e caminho do logo), date, round, candidates (ids de config/candidates.json) e sources. Cada fonte tem um id estável (por convenção <agência>-<id do debate>), o outlet (chave de config/outlets.json), o adapter e a url da página de cobertura.site/logos/.config/candidates.json, com aliases (nome do jeito que as agências escrevem, sem acento e em minúsculas), partyLogo e sprite. Os bonecos são pixel art definida em site/sprites/render.py. Um candidato novo precisa ser desenhado lá, com o mesmo corpo e o mesmo número de quadros de boca dos outros, e o script gera <sprite>.svg e <sprite>-talk.svg.config/outlets.json. Os rótulos dela vão em config/bands.json, cada um com sua faixa.pnpm ingest. O próximo ciclo do workflow faz o mesmo sozinho.Os leitores disponíveis estão em src/adapters/index.ts: g1-page, lupa-page, estadao-page e aosfatos. Uma fonte com adapter desconhecido falha e aparece no run-report.json, sem derrubar as outras. O config é validado antes de qualquer acesso à rede, e o erro diz qual campo está errado.
Um formato de página novo pede um leitor novo em src/adapters/, uma linha no registro de src/adapters/index.ts e testes. Cada leitor tem um version. Aumente esse número em qualquer mudança que altere o que ele extrai. Cada registro guarda em adapter o <tipo>@<versão> que produziu o conteúdo atual dele, e é por isso que dá para refazer a leitura de uma cópia antiga com o código certo.
Um rótulo que não está em config/bands.json é publicado como "sem faixa", aparece no run-report.json e deixa a execução do workflow vermelha no último passo (pnpm check:labels), depois que o site já foi publicado. O vermelho é o aviso para incluir o rótulo na tabela.
O workflow .github/workflows/update.yml roda a cada duas horas (minuto 17), a cada push em main e quando alguém dispara pela aba Actions. Ele testa, coleta, faz commit de data/ só quando algo mudou, monta o site e publica no Pages, tudo no mesmo job. Antes da primeira execução:
main.IA_S3_ACCESS (a access key) e IA_S3_SECRET (a secret key). Sem eles, as checagens novas saem sem cópia arquivada nem hash.main. Ele pede contents: write sozinho. Se houver proteção de branch ou ruleset em main, libere o github-actions[bot].update > Run workflow) e confira o resumo da execução.O campo accept_drop do disparo manual existe para quando uma agência apaga muitas checagens de verdade. Se uma fonte devolve menos de 80% dos registros publicados, o ingest marca a fonte como partial e mantém os registros antigos. Para aceitar a queda, dispare o workflow com o id da fonte nesse campo. Localmente, o equivalente é pnpm ingest --accept-drop=<id da fonte>.
Se o GitHub Actions for bloqueado por alguma agência (a Lupa fica atrás do Cloudflare), rode pnpm ingest na sua máquina e dê push. O push em main dispara o workflow, que monta e publica o site.
O GitHub desliga workflows agendados depois de 60 dias sem atividade no repositório. O disparo manual continua funcionando.
Todos em data/, gerados pelo ingest. Não edite à mão.
checks.json tem uma entrada por checagem, com id (fixo desde a primeira coleta), sourceId, debate, outlet, speaker (id do candidato), quote (a fala), label (o rótulo da agência, sem alteração), band (a faixa), excerpt (até 280 caracteres da explicação da agência), url (onde conferir), adapter, evidence (página lida, data da coleta, cópia arquivada e SHA-256 da cópia), além de missingSince e history quando for o caso.checks.csv tem as mesmas checagens, uma por linha, com evidence aberto nas colunas evidence_url, fetched_at, archive_url e sha256, e history como texto JSON. UTF-8, aspas no padrão RFC 4180.run-report.json resume a última execução por fonte: status (ok, failed ou partial), motivo da falha, versão do leitor, quantidade de checagens, itens excluídos (com o motivo), duplicados, rótulos sem faixa, comentários do Aos Fatos ainda sem selo e checagens esperando cópia arquivada. Não tem data nem hash por execução, então só muda quando algo de fato mudou.O site serve os três arquivos na raiz, junto com bands.json.
LICENSE.data/checks.json, data/checks.csv, data/run-report.json) e a tabela de faixas (config/bands.json): Creative Commons Atribuição 4.0 (CC BY 4.0).site/logos/): marcas dos seus donos, tiradas do Wikimedia Commons, usadas só para identificar. Também não estão cobertos pelas licenças acima.site/sprites/): desenhadas pelo projeto a partir dos retratos oficiais. Lula: Palácio do Planalto, CC BY 2.0. Flávio Bolsonaro: Agência Senado. Os dois retratos estão no Wikimedia Commons.site/fonts/): Inter e Inter Tight, de Rasmus Andersson e The Inter Project Authors, SIL Open Font License 1.1, tiradas dos pacotes npm @fontsource/inter 5.3.0 e @fontsource/inter-tight 5.3.0.Os detalhes estão em NOTICE.