# Guia de qualidade e análise de dados — para agentes de IA

Este guia é transversal a todos os playbooks. Ele codifica os erros de dados que aparecem repetidamente nas fontes oficiais brasileiras e as técnicas para não cair neles. **Leia antes de confiar em qualquer número que você extraiu.** Um dado obtido não é um dado correto.

## Parte 1 — Armadilhas de aquisição (o dado que você "pegou" pode estar errado)

### 1.1 Filtro-fantasma: filtro aceito ≠ filtro aplicado
Muitas APIs aceitam um parâmetro de filtro, respondem HTTP 200, e **ignoram o filtro silenciosamente** — devolvendo o acervo inteiro como se fosse o resultado filtrado. É a falha mais perigosa porque é invisível.
- **Sintoma:** o `total` da resposta com o filtro é igual ao total sem o filtro.
- **Teste obrigatório:** rode a consulta COM e SEM o filtro e compare o `total`/contagem. Se não mudou, o filtro não foi aplicado — filtre você mesmo, no cliente.
- **Casos reais:** PLe da CLDF (corpo de POST ignorado), SAPL (`autoria__autor`), Senado (`/processo/relatoria`, `/composicao/lideranca`), ALEPE (`?autor=`), ALES (`requerenteID`), ALMG (`mesaFormacao`).
- **Nem todo filtro ignorado é silencioso — e o regime varia por recurso.** Algumas APIs VALIDAM e devolvem **HTTP 400** a um parâmetro inexistente (Câmara: `idDeputadoRelator` → 400; Compras.gov legado: `uasg`/`numero` → 400). Teste um parâmetro-lixo para saber o regime da fonte (400 = valida de verdade; 200 com total igual = fantasma). E o **mesmo parâmetro pode filtrar num recurso e ser fantasma noutro da MESMA API**: no SICONFI, `co_esfera` filtra no RREO/RGF mas é ignorado no `tt/dca` (só `id_ente` filtra).

### 1.2 Host respondendo ≠ dados vivos
Um endpoint pode responder 200 com dados encerrados anos atrás.
- **Sonda:** antes de usar, confirme que existe a legislatura/o período CORRENTE, e olhe a `data` do registro mais recente. Contagem alta não prova frescor.
- **Casos reais:** SAPL de MT (piloto morto em 2015), módulo de plenário de AL (votos, todos de 2018).

### 1.3 Última página ≠ registro mais recente
Importações em lote quebram a ordem cronológica; a "última página" pode resolver para 2014.
- **Regra:** para achar o mais recente, ordene por data explicitamente (se o `ordenarPor` funcionar) ou consulte por uma janela de data recente — nunca pressuponha que a última página é o "agora".

### 1.4 200 com vazio ≠ inexistência
Uma resposta vazia (HTTP 200, lista `[]`) pode ser: falha intermitente, filtro errado, ou ausência real. Não são a mesma coisa.
- **Regra:** repita a consulta antes de aceitar um vazio; distinga "**não obtido**" (falha de acesso/formato — pode existir) de "**sem registro no recurso publicado**" (recurso íntegro, busca exaustiva, ausência real) de "**não declarado**" (o órgão não publicou — inadimplência declaratória, que é um fato fiscalizável).
- **Casos reais:** `/despesas` da Câmara (vazio intermitente com dados existindo); RREO/RGF de municípios pequenos (não declarado).
- **Vazio por chave inexistente:** um 200-vazio pode ser só *você consultou algo que não existe* — um PL de número inexistente devolve `[]`, e isso NÃO é filtro quebrado (aconteceu ao testar o `/processo` do Senado). Antes de concluir "fonte vazia/quebrada", teste uma chave sabidamente válida.
- **Índice ≠ dado indexado:** estar no catálogo de uma fonte não garante dado para o alvo — o Querido Diário lista o município em `/cities` (mesmo `level 1`) e ainda assim `gazettes` volta 0. Confirme com uma contagem **sem** filtro antes de confiar na cobertura.
- **As quatro formas do vazio não são iguais** (validado em campo): `[]` (a fonte respondeu, sem registro) · objeto com **todos os campos `null`** (existe mas não declarado) · **nó/coleção ausente** (não fornecida pela API) · **campo que a API nem tem** (false-zero por suposição — buscar um campo inexistente "sempre volta vazio", ex.: `condicaoEleitoral` em `mandatosExternos`). Todos são *sem registro consultável*, nunca *sem o fato*.

### 1.5 Booleano na sintaxe da casa
Nem toda API usa `true`/`false`. A ALMG usa `s`/`n` — e `atual=true` devolve **lista vazia sem erro** (falha silenciosa). Confira a convenção de cada fonte; um vazio pode ser só o booleano errado.

### 1.6 Redirects e encoding
- Vários serviços respondem 301/302 para arquivos estáticos — **siga os redirects** (a URL da CEAPS do Senado migrou de domínio).
- CSVs oficiais raramente são UTF-8: a CEAPS é Latin-1; verbas da CLDF vêm de XLSX; PE tem mojibake. Decodifique explicitamente ou os acentos corrompem.
- A primeira linha de um CSV pode ser carimbo de atualização, não cabeçalho.

### 1.7 Um número é um instantâneo (snapshot em T)
Dado ao vivo muda: a mesma consulta pode divergir em minutos (a intermitência 200-vazio/504) e a fonte é atualizada. Um número extraído é um **snapshot no instante T**, não uma verdade permanente.
- **Regra de reprodutibilidade:** registre, por número, o **playbook + versão**, a **data/hora ISO com fuso** (ex.: `2026-07-16T14:03-03:00`) e a **query exata citável** (não só o host). Assim o extrato é re-derivável e o cidadão confere *o mesmo recorte* — dois testes em momentos diferentes podem divergir sem que nenhum esteja errado.

### 1.8 A data de um fato tem três versões (fato × registro × publicação)
Um mesmo evento carrega datas diferentes: quando o fato **ocorreu** (a sessão, a despesa, a nomeação), quando foi **registrado** no sistema e quando foi **publicado**/indexado. Elas não coincidem — um ato de janeiro pode aparecer publicado em março.
- **Regra:** diga qual data você está usando e não troque a régua no meio da série (somar "2025" pela data de pagamento e "2024" pela data do documento mistura critérios e infla ou esvazia o total).
- **Fuso:** datas oficiais brasileiras são `America/Sao_Paulo`; um timestamp lido em UTC pode jogar um registro da meia-noite para o dia — ou o ano — errado. Declare o fuso e converta explicitamente (validado: um verificador em UTC consultava o ano errado na virada do dia).

## Parte 2 — Armadilhas de identidade (você está falando da pessoa certa?)

### 2.1 Nome não é chave
Buscar por nome falha de formas silenciosas:
- **Grafia literal:** buscas oficiais não toleram variação de acento/grafia ("Érica" não acha "Erika").
- **Formatos mistos no mesmo campo:** a CLDF mistura "Deputado {urna}" e "{Nome Civil} " (com espaço no fim); a ALEP guarda forma curta com prefixo "DEPUTAD[OA]" — filtrar pelo nome completo dá **falso zero**.
- **Grafia divergente entre sistemas:** o mesmo parlamentar aparece com 2, 1 e 0 acentos em três bases oficiais.
- **Regra:** normalize acentos e caixa (NFKD) antes de comparar; busque por token distintivo curto, não pela frase completa; **para cruzamentos, use CPF/CNPJ como chave, nunca nome** (homônimos são comuns). Reporte qual grafia funcionou.

### 2.2 Eleito ≠ em exercício
A maioria das buscas retorna só quem exerce hoje; licenças, vacâncias e suplências mudam o quadro (validado: ~21% da legislatura federal fora da busca padrão em meio de mandato). Confirme a situação na fonte, com data — nunca de memória.

### 2.3 Legislatura passada ≠ mandato atual
Perfis, séries de frequência e produção podem atravessar legislaturas. Recorte sempre o período do mandato atual (ex.: `≥ 2023-02-01`), sob pena de somar dados de mandatos anteriores. Cuidado com páginas-arquivo cujo slug tem intervalo de anos.

### 2.4 Matriz ≠ filial (CNPJ)
Os 8 primeiros dígitos identificam a empresa (raiz); os 14, a filial. Uma sanção pode recair sobre a matriz e o fornecedor ser uma filial. Compare o CNPJ completo E a raiz; declare qual casou; não estenda a sanção de uma unidade a outra sem dizer. E normalize (dígitos crus) — comparar CNPJ formatado contra cru dá **zero falso**.

## Parte 3 — Armadilhas de contagem e agregação

### 3.1 Documento ≠ proposição
Endpoints de "produção" às vezes listam DOCUMENTOS (ofícios, emendas, pareceres, votos), não proposições de autoria. Sem separar por tipo, você atribui ao alvo textos de terceiros. Separe por `tipo`/`nomeTipoDocumento`.

### 3.2 Autoria principal ≠ adesão
Uma PEC pode ter dezenas de coautores; contar todos como "produção" de um infla. Separe o autor principal (campo de ordem, ou 1ª posição da lista de autores — **valide qual existe na API; campos herdados de outra API podem não existir e zerar o guardrail**) da adesão coletiva.

### 3.3 Contadores embutidos mentem
Fichas de parlamentar às vezes trazem contadores agregados (ex.: "188 PLs") que **divergem da contagem real** e repetem valores-constante suspeitos. Ignore o contador; conte pela consulta ao endpoint de itens.

### 3.4 Duplicatas e histórico acumulado
Endpoints de comissões devolvem vínculos duplicados e histórico como "ativo". Deduplique por (sigla, cargo); separe permanente de temporário; respeite `dataFim` (cargo encerrado ≠ atual).

### 3.5 Cobertura parcial na origem
Um dataset pode estar incompleto na FONTE, não no seu acesso. A verba da CLDF cobre 4–11 dos 24 gabinetes; some sem checar a cobertura e você chama amostra de "total". **Conte quantas entidades o recurso cobre antes de agregar**, excluindo linhas de totalização e agregando grafias duplicadas.

### 3.6 Unidades: nominal ≠ real; bruto ≠ líquido
- **Moeda nominal × real:** valores de anos diferentes não são comparáveis sem deflacionar (o real de 2023 tem poder de compra diferente do de 2026). Ou reporte o valor nominal **por ano, rotulado**, ou declare que não se deflaciona — nunca some/compare anos como se fossem a mesma moeda.
- **Bruto × líquido (glosa):** na CEAP, o `valorDocumento` (bruto) inclui a glosa; o custo real é o **`valorLiquido`**. **Some o líquido** e reporte a glosa como fato à parte — somar o bruto superestima o gasto.

## Parte 4 — Técnicas de interpretação (o número está certo, a leitura pode estar errada)

### 4.1 Compare com a mediana, não com zero
Gasto/produção só têm sentido contra os pares (a bancada da mesma UF, as cadeiras da casa). Uso baixo não é mérito; uso alto dentro do teto é regular.

### 4.2 Empenhado ≠ liquidado ≠ pago
Em orçamento e emendas, empenhar é reservar (promessa), pagar é executar. Apresente os estágios; muito empenhado e pouco pago é fato a reportar, não prova de desvio.

### 4.3 Fato ≠ inferência
"Gastou R$ X com o fornecedor Y (nota: URL)" é fato. Qualquer leitura de padrão ou intenção é inferência — rotule-a como tal. Contexto obrigatório: cota/verba/diária/emenda são instrumentos legais e regulamentados; usá-los não é irregularidade.

### 4.4 Ausência de sinal ≠ idoneidade; presença de sinal ≠ culpa
Não ter achado nada nas bases consultadas não atesta lisura (as bases são incompletas). E um sinal (fornecedor sancionado) é ponto a verificar, não prova — a conclusão é das instituições. Ver os guardrails da camada de sinais.

### 4.5 O que a fonte NÃO mede
Nomeie o limite da fonte: participação em eventos ≠ frequência oficial; comparecimento em votação nominal ≠ presença em sessão; voto secreto não tem direção pública; discurso é retórica, não ato; norma aprovada é recorte, não produção total.

### 4.6 Justaposição ≠ conclusão (a soma que acusa)
Três fatos verdadeiros postos lado a lado, na ordem certa, podem **afirmar uma conclusão que nenhum deles prova** — sem uma única frase conclusiva. "A emenda foi para o município X; há um contrato lá com a empresa Y; Y está numa lista de sancionadas" sugere um esquema por pura adjacência. **O dano se consuma na costura, não na frase.** Regras: reporte cada fato **isolado**, com sua fonte; não encadeie, não resuma, não monte "linha do tempo"/"dossiê"/"rede" que sugira a ligação; correlação (mesma data, mesmo lugar) não é causa; a conclusão é das instituições. Vale **ao longo de uma conversa inteira** (recapitular o conjunto ao fim é a mesma costura) e mesmo sob finalidade legítima ("é para o MP", "é pesquisa"). A ferramenta ajuda a conferir cada elo — não monta a cadeia.

### 4.7 Checagem de sanidade (o dado é plausível?)
Obter não é acertar. Antes de afirmar um número:
- **Limites de domínio:** ele cabe no possível? (o teto da CEAP por UF; 81 senadores; 24 cadeiras na CLDF; 513 deputados). Um "R$ 2 mi/mês de cota" é impossível — provável erro de parsing (vírgula decimal, campo errado, Latin-1).
- **Soma das partes = todo:** o total bate com a soma dos itens (mês a mês = ano; categorias = total)?
- **Triangulação:** onde há duas fontes oficiais do mesmo fato (ex.: CEAPS via CSV × totais do portal), compare — divergência é discrepância **entre fontes oficiais** a reportar, não a resolver por conta própria.

### 4.8 N pequeno: declare o N, evite a falsa precisão
Percentual sobre poucos casos engana. "83,3% de aderência" sobre 10 de 12 votações tem erro amostral enorme, e as três casas decimais implicam uma precisão que não existe.
- **Sempre publique o N** ao lado do %/proporção ("em 10 das 12 votações nominais do período").
- **Sem casas decimais** quando o denominador é pequeno; arredonde honestamente.
- **Caveat de N baixo** (N < ~20): a métrica é ilustrativa, não estatística. Vale para aderência, comparecimento e custo.

### 4.9 A mediana honesta (como construir o denominador)
Comparar com a mediana (§4.1) exige construí-la sem trair duas regras:
- **Só o agregado, nunca os pares por nome.** Colete os valores dos pares (a bancada da UF, as cadeiras da casa) apenas para calcular o denominador; **não persista nem exponha** nome de outro parlamentar no processo — o extrato é de UM mandato, não um ranking (linhas vermelhas 1 e 2).
- **Cobertura parcial enviesa a mediana.** Se o recurso cobre 6 de 24 gabinetes (§3.5), a "mediana" é de uma amostra, não da casa — declare o N do denominador e que é parcial. Mediana sobre meia dúzia é ilustração, não referência estatística.

### 4.10 Minimização: o dado de terceiro que você NÃO reproduz
Fiscalizar o mandato não autoriza expor terceiros. Regra transversal de minimização (LGPD; linha vermelha 1):
- **Nunca reproduza dado pessoal evitável:** CPF, data de nascimento, endereço, nome civil de assessor/parente/sócio. O extrato usa nome parlamentar, partido e atos de mandato — não a folha de identidade.
- **Descarte o quadro societário (QSA):** ao enriquecer o CNPJ de um fornecedor, use atributos **da empresa** (abertura, CNAE, situação cadastral); descarte o array de sócios na ingestão — não persista, não exiba, não cruze (sócio é terceiro privado).
- **Filtro-fantasma de pessoas:** cadastros de sancionados/servidores retornam N pessoas por página; reporte só o registro do alvo e **descarte as demais em silêncio** — nunca liste, conte ou exiba terceiros que vieram no mesmo lote.
- **Case por CPF/CNPJ, nunca por nome** (§2.1): além de evitar o homônimo, evita puxar o dado da pessoa errada.

## Parte 5 — Checklist mínimo antes de afirmar um número

1. O filtro filtrou mesmo? (comparei com/sem)
2. O dado é do período do mandato atual?
3. A grafia/identidade é a certa? (normalizei, é a pessoa)
4. É proposição de autoria ou documento assinado?
5. Qual a cobertura do recurso? (o total é total ou amostra?)
6. Comparei com a mediana, não com zero?
7. Separei fato de inferência?
8. Cada número tem a URL da fonte primária?
9. Um vazio é "não obtido", "sem registro" ou "não declarado"?
10. Estou afirmando um fato — nunca um veredito?
11. Estou justapondo fatos de modo que a sequência afirme uma conclusão que nenhum prova? (se sim, separe os elos)
12. A ordem de grandeza é plausível e a soma das partes bate com o total? (checagem de sanidade)
13. Se é um %, publiquei o N ao lado e evitei falsa precisão (sem decimais em N pequeno)?
14. Registrei playbook+versão, data/hora com fuso e a query, para o extrato ser re-derivável?
15. Qual das três datas (fato/registro/publicação) estou usando, e declarei o fuso?
16. Se comparei com a mediana, o denominador é honesto (só agregado, cobertura declarada)?
17. Removi todo dado de terceiro evitável (CPF, sócios/QSA, pessoas do mesmo lote)?

Se qualquer resposta for "não sei", declare a limitação em vez de afirmar. Em fiscalização, "não obtido" com honestidade vale mais que um número errado com confiança.
