Quase toda empresa deste mercado publica um número de acurácia. Pergunte qual é o denominador e normalmente não há nenhum publicado. Esta página é a outra metade da pergunta: com que frequência este motor erra sobre um documento legítimo, com que frequência acerta sobre um adulterado separado por como a adulteração foi feita, e um caso em que a resposta honesta é que ele não detecta nada.
A página irmã é a matriz de evasão medida (em inglês): o que cada etapa de lavagem de fato derrota, com cada célula datada e reproduzível a partir de um bench versionado. Uma lavagem em dois passos leva um documento forjado de 70 para 10; um flatten para raster silencia 34 de 35 arquivos que disparavam.
As duas células escuras são as duas medições desta página, cada uma com a versão do motor e a data em que foi feita. As claras são o complemento aritmético de cada linha, e não medições separadas.
Como ler um número desta página
Em todo o resto deste site, uma página de guia não pode carregar um número que vai envelhecer. Afirmações datadas ficam no blog, onde a data delimita o que foi dito. Esta página é a exceção deliberada, e ela é contida de duas formas em vez de ficar na boa intenção.
- Cada número traz a versão do motor em que foi medido e a data. Uma taxa medida na 1.17.0 é uma afirmação sobre a 1.17.0. Onde uma versão posterior mexeu no número, os dois valores estão aqui, e a versão que mexeu também.
-
Um teste na CI prende esta página ao motor publicado.
Ele verifica que a versão que esta página chama de atual é a versão
que está no código do motor. Então nenhuma release do motor sobe sem
que alguém volte e releia o que está escrito aqui. O motor rodando em
produção hoje é a 1.37.0. Essa
versão adiciona a décima nona família de sinais,
extraction-anomalies: páginas cujo texto extraído não é confiável como o texto que um leitor vê, medida em 5.168 documentos publicados antes de qualquer severidade (docs/CORPUS-PHASE0-EXTRACTION-2026-08-31.md no repositório). A versão anterior, 1.36.0, não mudou nada no motor: é uma leva de correções de segurança, lançada só para que os fixes cheguem ao pacote MCP publicado no npm. O servidor MCP agora tranca fora da resposta doinspect_documento texto recuperado sob uma tarja quando ele tem forma de prompt injection, ganha uma allow-list opcional de leituraTAMPERLENS_ALLOWED_DIRSque confina umpathlocal a diretórios nomeados, e endurece o upload docompare_documents; o webhook de cobrança, que é do servidor e fora do motor, passa a liberar a entrega só pelopayment_statusdo Stripe. Todo laudo é byte a byte igual a um da 1.35.0; o número só subiu porque o pacote MCP publicado é fixado na versão do motor. A versão anterior, a 1.35.0, também não mudou nada no motor: deu às ferramentas do servidor MCP uma alternativaurlao caminho de arquivo local, para um agente apontar um link http ou https e o servidor buscar o documento pela rede da própria máquina antes de enviar os bytes. Antes dela, a 1.34.0 acrescentou um bloco de custo de I/O medido a todo laudo e um escopo barato?mode=triage, para um agente decidir se um documento vale uma inspeção completa. Foi medida antes no mesmo corpus de 5.168 documentos: a triagem expande 9% dos bytes descomprimidos de uma análise completa, reproduz as famílias estruturais, de metadados e de assinatura número por número, e fica em silêncio nas famílias de conteúdo de página, o que o blocotriagedo laudo diz, em vez de deixar inferir. Não moveu nenhuma severidade nem nenhum número de especificidade desta página, e cada um continua atribuído à versão em que foi medido. Antes dela, a 1.33.0 acrescentou duas detecções à famíliaactive-content(um nome escondido por hex-escape e a chave/AA), cada uma medida no mesmo corpus. A 1.31.0 juntou três famílias de sinais de Office em um sinal cada, que é o que a regra do laudo sempre disse que elas eram; ela também não mudou comportamento de PDF nem de imagem, e todo número abaixo foi medido sobre corpora de PDF. Cada um continua atribuído à versão em que foi medido. A 1.30.0 mudou a contagem de revisões quando um trailer anexado omite/Prev, o teto de chunks de PNG, os padrões de nome de gerador e o fator de vencimento do boleto, e se algum documento das duas populações tem o trailer sem/Prevcontinua não verificado.
Duas palavras são usadas com rigor daqui para baixo. Medição significa que o motor rodou sobre os arquivos. Projeção significa que o cálculo de pontuação foi reexecutado sobre laudos já armazenados, o que é mais fraco, e sempre que aparece está rotulado assim.
Nenhum número desta página aparece sem um destes três rótulos. Um teste na CI prende a versão que a página chama de atual à versão que o motor publica, então nenhuma release sobe sem que alguém releia o que está escrito aqui.
Falsos positivos em 1.728 documentos que ninguém selecionou
Todo corpus que este motor tinha até agosto de 2026 foi escolhido por nós. Processos judiciais, contratos do PNCP, amostras de extrato. Uma taxa calculada sobre documentos que você escolheu é um fato sobre a escolha, não sobre o motor. Então foram medidas duas populações que ninguém aqui montou:
- 743 PDFs da web brasileira, sorteados de blocos igualmente espaçados do índice do Common Crawl, em 421 hosts brasileiros. É a população que se parece com o que chega na sua mesa: comprovante de residência, holerite, contrato, nota.
-
985 PDFs de
.govamericanos, do conjunto aleatório “1000 .gov PDF dataset” da Library of Congress (CC0), como contraprova de uma população estrangeira e igualmente não curada.
- 1.728documentos publicados, nenhum escolhido por nós
- 0falhas de parsing
- 4 ago 2026a data da medição
Todos foram publicados pela própria organização que os produziu, então cada um é presumido legítimo e qualquer pontuação acima de baixo conta contra nós. É essa medição que forçou a reespecificação do motor 1.17.0: quatro famílias de sinal foram limitadas ou reescopadas porque afirmavam “alterado depois de criado” sobre arquivos cuja própria contagem de revisões diz que foram escritos uma única vez.
| População | Acima de baixo | Na faixa alto |
|---|---|---|
| Web brasileira (743) | 82,8% → 30,0% | 38,2% → 10,0% |
.gov americano (985) |
68,5% → 18,6% | 11,8% → 7,4% |
À esquerda da seta: medido, no motor como ele estava antes da 1.17.0, 4 de agosto de 2026. À direita: motor 1.17.0, 4 de agosto de 2026, uma projeção, não uma nova medição.
A coluna da direita é uma projeção e não vamos chamá-la de outra coisa. Ela vem de reexecutar o cálculo de pontuação sobre os laudos já armazenados dos 1.728 documentos, porque as regras do corpus apagam os arquivos originais depois de cada rodada. O que a torna confiável é que a reexecução reproduz a faixa atual do motor em 1.728 de 1.728 documentos; o que a mantém uma projeção é que ninguém rebaixou os bytes e rodou o motor inteiro de novo. Os dois manifestos de coleta sobreviveram, então uma nova rodada de verdade é reproduzível. Ela não foi feita.
Isso não foi remedido no nível da população inteira desde a
1.17.0, e a leitura honesta da lacuna é que o número acima
está, se tanto, alto demais para o motor de hoje: 1.19.0, 1.22.0 e
1.23.0 tiraram disparos dessas mesmas populações em vez de acrescentar,
e a verificação nova da 1.27.0 entra como low, que sozinha
não tira um documento da faixa baixo. O relato da rodada
original, com as quatro famílias e o que cada uma fazia de errado, está
aqui.
Por que a amostra brasileira dispara mais
A diferença entre 82,8% e 68,5% não é sobre o Brasil produzir documento pior. É estrutural, e vale entender antes de olhar qualquer laudo daqui.
Uma assinatura ICP-Brasil anexa uma revisão incremental por signatário. Um contrato assinado por três pessoas tem três revisões: exatamente a forma que um detector ingênuo chama de adulteração. Some a isso os fluxos de cá: o documento sai de um sistema, passa por um portal que reescreve o arquivo, é assinado, é carimbado com protocolo. Cada etapa é uma escrita legítima que deixa marca. Rodamos 250 contratos do PNCP, 62 modelos de governo e 33 PDFs publicados por bancos para separar as duas coisas; o relato está aqui.
O desenho mostra por que a amostra brasileira dispara mais, e não que ela contenha documento pior. As etapas foram separadas rodando 250 contratos do PNCP, 62 modelos de governo e 33 PDFs publicados por bancos; o relato está aqui.
A consequência prática é a que este site repete em todo lugar: revisão não é fraude. O motor reporta a estrutura e a evidência bruta; quem decide é você, com o contexto que o arquivo não carrega. É também por isso que a reespecificação da 1.17.0 derrubou a faixa alto brasileira de 38,2% para 10,0%: a maior queda das quatro células da tabela acima.
Detecção, por tipo de adulteração
Especificidade é a metade fácil: documento legítimo se acha aos milhares. A outra metade é difícil, porque nenhum corpus público rotula documentos como adulterados. Os conjuntos acadêmicos de falsificação são forense de imagem em nível de pixel, e os corpora de PDF guardam arquivos malformados e maliciosos, que é outro problema. Um PDF malicioso ataca o leitor; um adulterado mente para ele.
Então os positivos foram construídos. 160 documentos
legítimos, publicados pelos próprios emissores e tirados das
duas populações acima, todos pontuando baixo e com uma
única revisão antes da edição (para não haver falso positivo
embutido no resultado), com oito edições conhecidas aplicadas a cada um,
gerando 1.006 arquivos adulterados. Que eles são
adulterações e não arquivos quebrados foi verificado de três formas:
qpdf --check devolveu 944 limpos, 62 com aviso e 0
quebrados, e todo aviso vem de uma fonte que já os tinha; as páginas
foram renderizadas e inspecionadas; e cada retângulo de cobertura foi
mirado num trecho de texto que o parser tinha retido, não numa faixa
chutada: caixa sobre espaço em branco não esconde nada.
O que o desenho não mostra é o limite mais duro desta metade da página: oito operações aplicadas por um script não são um adversário. Estas são as adulterações em que nós pensamos.
| Como a adulteração foi feita | Detectado |
|---|---|
| Edição salva como revisão incremental: caixa sobre um valor, tarja preta, linha redigitada | 100% |
| Imagem enxertada na página | 100% |
| Edição seguida de remoção dos metadados | 100% |
| Composição por Form XObject: o que um editor de PDF online escreve | 89,4% |
Edição e reescrita do arquivo inteiro pelo qpdf |
71,1% |
| Edição e redestilação do arquivo inteiro pelo Ghostscript | 65,5% |
Medido, motor 1.23.0, 5 de agosto de 2026: 1.006 arquivos adulterados a partir de 160 fontes legítimas, rebaixadas byte a byte idênticas, com 0 confusões: nenhuma das 160 fontes pontuava acima de baixo antes de ser editada. Primeira rodada na 1.18.0 (4 de agosto de 2026); remedido e idêntico até a casa decimal na 1.19.0, 1.22.0 e 1.23.0.
Não publicamos o número agregado, e isso é uma decisão, não um esquecimento. Uma média entre as oito operações trataria o fraudador como quem sorteia uniformemente entre elas. Ninguém mediu essa distribuição, ela é certamente falsa, e é exatamente o número que vira propaganda sem denominador. As linhas da tabela são a afirmação.
Em uma frase: a adulteração ingênua é pega sempre; a composição por Form XObject é pega em cerca de 9 de cada 10 casos; lavar o arquivo inteiro numa reescrita derruba a detecção para uns dois terços. A linha do Form XObject era 0,7% antes do motor 1.18.0 (4 de agosto de 2026). O leitor de conteúdo parava na fronteira do formulário, então uma caixa branca desenhada dentro de um nunca era comparada com o texto embaixo. Isso era divulgado em todo laudo na época, o que era honesto e não tornava a falha mais barata.
E delimita o que o número significa: estas são as adulterações em que nós pensamos. Oito operações aplicadas por um script não são um adversário.
O resultado nulo: um arquivo gerado limpo
Todo número de detecção acima parte de um documento legítimo e aplica uma edição: a classe para a qual a forense de bytes existe. A classe que ninguém tinha medido é a que nunca foi editada: um documento diagramado e impresso do zero, já com conteúdo falso desde o primeiro byte. No Brasil isso tem nome e endereço: o holerite e o comprovante feitos num gerador, não adulterados a partir do original do banco.
Vinte deles foram construídos: 8 imitações de extrato e holerite
diagramadas em HTML e impressas pelo Chromium headless, 6 adulterações
já detectadas achatadas em imagem com pdftoppm, e 6
escritas byte a byte numa passada limpa, com string de produtor de
biblioteca de servidor ou sem string nenhuma.
0 de 20 pontuaram acima de baixo: motor 1.22.0, medido em 4 de agosto de 2026. O número mais duro está na classe achatada: os mesmos seis documentos, com o mesmo conteúdo falso, pontuam alto em 100 como edição incremental e baixo em 10 depois de uma única rasterização. Um comando lava para zero uma adulteração que era pega inteira.
Medido no motor 1.22.0, em 4 de agosto de 2026, sobre os 20 documentos gerados do zero descritos acima. A resposta à segunda pergunta tem de vir de outro lugar. Uma linha de base do emissor, o Open Finance, um telefonema para o RH, e se linhas de base privadas pegam essa classe ainda não foi medido.
Isso não é um defeito, e não vamos consertar com limiar.
Nada foi editado, então não há edição a encontrar. O motor se comportou
exatamente como projetado no mesmo teste: os subconjuntos de fonte do
Chromium e os pares /ID novos saíram como info,
pontuando zero, que é precisamente para o que serviu a recalibração da
1.17.0: um motor anterior à 1.17 teria “pego” as oito impressões do
Chromium e estaria errado sobre o motivo.
O que isso significa na prática é uma regra de escopo, não uma ressalva: este motor responde este arquivo foi alterado depois de feito. Ele não responde este documento é verdadeiro. Um arquivo gerado limpo é a fronteira entre as duas perguntas, e a resposta da segunda tem de vir de outro lugar. Uma linha de base do emissor, o Open Finance, um telefonema para o RH. Se linhas de base privadas do emissor pegam essa classe ainda não foi medido, e é o próximo benchmark.
A única família que sobrevive à lavagem do arquivo
A redaction-exposure pergunta se o texto que alguém quis
remover continua legível embaixo da tarja desenhada sobre ele. Ela pesa
de forma desproporcional por um motivo: é a única família de sinal que
sobrevive a uma reescrita do arquivo inteiro, a reescrita destrói o
histórico de revisões que todas as outras leem, mas texto embaixo de uma
caixa continua sendo texto embaixo de uma caixa. Ela respondeu por
38,3% de todas as detecções no conjunto adulterado, e
por cerca de 41% do que sobra depois de uma reescrita.
Ela também foi, por um tempo, nossa pior fonte de falso positivo, e corrigi-la valeu todo esse trabalho justamente pelo parágrafo acima. O método não envolveu ler nenhum documento pelo conteúdo: renderize a página e olhe os pixels onde o trecho supostamente escondido está. Texto embaixo de uma caixa é um bloco chapado; texto que não está escondido tem o contraste de glifos. Em 1.693 trechos cobertos, nada ficou entre 0,7 e 12,2. O limiar é um vazio nos dados, não uma constante calibrada.
Eixo esquemático: o desenho mostra a separação entre os dois agrupamentos, não a densidade dentro de cada um. É a família que pesa de forma desproporcional pelo motivo do parágrafo acima: uma reescrita do arquivo inteiro destrói o histórico de revisões que todas as outras leem, e texto embaixo de uma caixa continua sendo texto embaixo de uma caixa.
| Motor | Web brasileira | .gov americano |
O que mudou |
|---|---|---|---|
| 1.18.0 · 4 ago 2026 | 17,0% | 5,1% | O ponto de partida |
| 1.19.0 · 4 ago 2026 | 49/743: 6,6% | 19/985: 1,9% | Caminhos de recorte eram ignorados (85% dos documentos que disparavam definem um); um trecho coberto só de espaços era reportado como texto coberto |
| 1.22.0 · 5 ago 2026 | 46/742: 6,2% | 18/985: 1,8% | Recortes desenhados com linhas, e não com retângulos, passaram a ser reconhecidos |
| 1.23.0 · 5 ago 2026 | 29/742 | 16/985 | Imagem desenhada sobre texto deixou de pontuar |
A detecção fica inalterada em cada um desses passos. A tabela por tipo de adulteração foi remedida depois de cada um e é idêntica até a casa decimal, com 0 adulterações perdidas. E o achado que mais importa para quem lê um laudo: nesses 1.728 documentos publicados, esta família não encontrou nenhuma tarja mal feita, em nenhuma das duas populações. Cerca de 9 em cada 10 dos disparos originais eram comprovadamente errados ou vazios.
O que sobra está declarado, não escondido. O resíduo depois da 1.19.0
eram 18 documentos americanos: doze falsos positivos genuínos, vindos de
recortes não retangulares que este parser não modela, e seis que
escondem texto de verdade, todos artefato de diagramação, rótulo de
gráfico atrás do preenchimento, mapa sobre o próprio parágrafo de
rascunho, rodapé de modelo. O rebaixamento da imagem-cobertura na 1.23.0
foi decidido do mesmo jeito: nas 1.006 adulterações, imagens cobrindo
texto responderam por zero detecções, contra 385 das
caixas preenchidas. Então a observação continua no laudo como
info e deixa de pontuar.
O verificador de tarja roda
exatamente esta família num arquivo que você tem em mãos.
O mesmo número, por ferramenta
Uma taxa de falso positivo sobre a população inteira é o número certo para decidir se vale contratar isto. É o número errado para ler um laudo específico, porque a taxa não é espalhada por igual. Ela é, em boa parte, uma propriedade do software que escreveu o arquivo. Dentro de uma mesma população, a taxa de disparo de um sinal foi de 0% a 100% conforme o programa que gerou o documento. É isso que um achado anterior, um corpus muito mais barulhento que outro, acabou sendo: efeito de produtor vestido de efeito de origem.
Por isso a versão por ferramenta do número principal desta página já
existe: a referência de
strings de produtor lista as 40 strings /Producer
frequentes o bastante naquele corpus para terem sido medidas, e a última
coluna dela é a nossa própria taxa de falso positivo sobre a
saída legítima daquela ferramenta, nunca uma taxa de fraude.
Todo documento por trás dela foi publicado pela organização que o fez,
então lá também cada pontuação acima de baixo conta contra nós.
Mesmo corpus, pontuado no motor 1.22.0: 432 strings de produtor distintas nos 1.728 documentos, 252 delas aparecendo uma única vez. O que é o fato mais útil daquela página. A cauda longa é o caso normal, e uma string que você nunca viu não é evidência de nada.
As medições que falharam
A regra da casa é que nenhuma verificação entra no motor antes de ser medida contra o corpus, e quando a medição falha, o que se publica é a falha, não a verificação. Várias verificações planejadas não existem neste motor hoje porque uma medição disse não, e um dos critérios não pôde ser lido de jeito nenhum. Tirar estas linhas desta página baratearia todos os números favoráveis acima.
O critério do boleto não pôde ser lido: n ≈ 0. Um decodificador de código de barras de boleto estava condicionado a um número, que fração dos boletos reais carrega um código de barras vetorial decodificável. Varrendo 3.822 PDFs do corpus (motor 1.20.0, 5 de agosto de 2026), apareceram 63 documentos “com cara de boleto”; só 2 carregavam uma linha digitável, e os dois são especificações de layout bancário citando uma linha de exemplo. Todos os 15 aparentes códigos de barras vetoriais, abertos um a um, eram filetes de tabela e borda de célula. O corpus não contém boletos, então o critério fica sem leitura e o decodificador não foi construído. E isso não se resolve baixando boletos de verdade: um boleto é a conta de um estranho, com o nome dele e quase sempre o CPF, e as regras do corpus fecham esse caminho por construção.
A primeira rodada daquele script merece a própria frase, porque ela parecia uma resposta: reportou um 0 limpo nos 3.822 documentos, e o 0 era um artefato: a varredura rodou sobre bytes de stream comprimidos que ela não conseguia enxergar. Uma medição que não enxerga o que mede devolve zero, e zero é indistinguível de um resultado.
Todos os 15 aparentes códigos de barras vetoriais, abertos um a um, eram filetes de tabela e borda de célula. E isso não se resolve baixando boletos de verdade: um boleto é a conta de um estranho, com o nome dele e quase sempre o CPF, e as regras do corpus fecham esse caminho por construção.
| Verificação planejada | O que a medição disse | Decisão |
|---|---|---|
| Coluna de valores contra o total declarado | De 114 totais candidatos em 3.842 documentos publicados, 56 (49,1%) leram como inconsistentes, o que é uma afirmação sobre o extrator, não sobre os documentos; 29 documentos legítimos teriam sido acusados. Motor 1.25.0, 5 de ago de 2026. | Não construída |
| Aritmética de holerite (bruto − descontos = líquido) | A população é de 3 documentos em 3.842: dois dos quais este repositório escreveu. | Não construída |
| Checksum de payload PIX (CRC-16 sobre o BR Code) | O corpus contém zero payloads PIX: 85 linhas carregam o marcador EMV e nenhuma se resolve como BR Code: então a taxa com que payloads reais falham não está medida. O que foi medido é a superfície de falso positivo: as 85 quase-candidatas foram todas rejeitadas. Motor 1.26.0, 5 de ago de 2026. | Entra uma severidade abaixo de onde o plano a colocava, até existir uma população real |
| Geometria de glifos: três das quatro verificações planejadas | Cada verificação rejeitada dispara em mais documentos publicados do que a regra inteira do plano pega adulterações; a verificação de linha de base sozinha marca 30,7% dos documentos brasileiros e 20,8% dos americanos que desenham texto. Motor 1.27.0, 5 de ago de 2026. | Não entram como achados. Só a variante de
linha com dinheiro entra, como low: 14 de 628
documentos publicados brasileiros e 10 de 740 americanos que
desenham texto (2,2% / 1,4%): e, pareada contra a
própria fonte de cada adulteração, ganho de 0,0% nas 228
adulterações que não redigitam nada |
Uma medição publicada estava ela mesma errada, e a retratação
faz parte do registro. A primeira rodada de fase 0 para
permissões de certificação enumerou 8 dos 14 alvos do corpus, 915 PDFs onde o corpus tinha 3.842, e chegou a três
conclusões que a rodada completa mostrou serem falsas, inclusive
“ninguém neste corpus certifica nada”. A rodada completa (motor
1.24.0, 5 de agosto de 2026) achou 12 documentos certificados, todos
os genuínos declarando /P 1, nenhuma alteração
permitida, onde o plano previa que o valor estaria todo no
/P 2. A premissa não estava um pouco fora; estava
invertida. A mesma rodada pegou a família lendo a imagem de aparência
da própria assinatura como alteração de conteúdo proibida, 109 disparos contrafactuais indevidos, 0 depois da
correção da 1.24.0, e a família disparou 0 vezes acima de
info em 273 documentos assinados. Os dois
relatórios estão no repositório, o primeiro sob um aviso dizendo o
que ele errou.
Até os resultados limpos deste bloco de trabalho vêm com os próprios
limites. A running-balance-break disparou 0 vezes em
3.842 documentos publicados, e a precondição dela nunca encontrou um
extrato bancário de verdade, porque o corpus guarda tarifários
publicados pelos bancos, não extratos de clientes, e nunca vai
guardar. Zero disparos não é a mesma afirmação que precisão medida
alta. A verificação de número de processo CNJ validou 156 de 156
números reais com 0 acusações falsas, e a detecção medida dela sobre
as 1.006 adulterações é zero, as adulterações mexem
em valores e datas, não em referências de processo.
O que ainda não foi medido
Uma página de medições que lista só as favoráveis é propaganda. Estas são as perguntas em que a resposta honesta hoje é que não temos número.
- Se linhas de base do emissor pegam um arquivo gerado limpo. É a contramedida que vendemos para o resultado nulo acima, e ela não passou por benchmark. Vai ser medida e publicada de um jeito ou de outro.
- Uma taxa de falso positivo de população inteira no motor atual. O que existe é a projeção da 1.17.0 acima, mais as remedições por família na 1.19.0, 1.22.0 e 1.23.0. A rodada completa é reproduzível a partir dos manifestos que sobreviveram e não foi feita.
- Uma taxa de verdadeiro positivo contra fraude real. Todo número de detecção desta página é medido contra adulterações que este repositório construiu, porque documento fraudulento de verdade não se obtém legalmente em escala: um extrato ou boleto falsificado real é dado pessoal de um estranho e quase sempre prova na disputa de outra pessoa, e as regras do corpus fecham esse caminho por construção. Nenhum número aqui diz com que frequência o motor pega a fraude como ela realmente chega.
- Detecção contra um adversário real. Os positivos são construídos por um script a partir de oito operações que nós escolhemos. Nada aqui diz como o motor se sai contra quem lê esta página.
-
Se um falsário esconderia texto em uma camada. Um
PDF pode carregar conteúdo em um grupo de conteúdo opcional
desligado por padrão: está no arquivo e não está na tela. O motor
1.28.0 lê e guarda esses trechos e não julga nenhum, e a mesma versão
estabeleceu que
glyph-anomalies,br-identifier-checksumerunning-balance-breakleem esse texto como se estivesse na página. Medido nos mesmos 1.727 documentos e remedido em 07/08/2026, depois que descobrimos que a primeira medição estava errada.
A rodada de 06/08/2026 decidia o que estava "desligado" apenas pelas listas/ON,/OFFe/BaseStateda configuração padrão. Visibilidade não é uma chave só: a configuração também pode trazer/AS, e um grupo cujo/Usage /View /ViewStateé/OFFfica invisível na tela independentemente do que as listas digam. O motor 1.28.0 contava esse grupo como visível. A falha foi apontada por um leitor, Tobias (@to21as), num comentário no nosso próprio post sobre tarja, que é a resposta honesta sobre como ela apareceu. O motor 1.29.0 lê/AS, e estas são as duas rodadas, lado a lado:
declaram conteúdo opcional 85 · 4,92% → 85 · 4,92%
grupo desligado por padrão 3 · 0,17% → 4 · 0,23%
pintam texto na camada 0 · 0,00% → 0 · 0,00%
1.28.0 1.29.0
A correção era real e era pequena. Um documento a mais, e o número que sustenta o argumento não se moveu: continua nenhum dos 1.727 pintando texto em camada desligada, e as três famílias continuam não lendo nenhuma linha oculta. Só 5 documentos (0,29%) trazem/AS, todos na amostra norte-americana.gov; a amostra brasileira não traz nenhum, então as contagens dela nunca foram afetadas.
Uma coisa que a remedição encontrou e a primeira rodada não podia ver, e é o caso mais afiado que Tobias nomeou: os dois documentos norte-americanos com camada oculta estão desligados em/Viewe ligados em/Print: parecem tarjados no leitor e na captura de tela, e imprimem o que está escondido. Essa forma não tem retorno nenhum. São 2 documentos em 1.727, e preferimos publicar o número a publicar a impressão.
E o limite mais antigo continua embaixo de tudo isso: são documentos em que ninguém estava escondendo nada. Um resultado nulo em arquivo publicado é evidência sobre acidente, não sobre adversário.
Ampliado em 07/08/2026 para todo documento real que temos. Os 1.727 acima são o corpus em que a medição de 1.28.0 foi feita, e a comparação tinha de continuar neles: senão mudança de definição e mudança de corpus ficariam indistinguíveis. A afirmação isolada não para ali: em ≈3.687 documentos distintos : somando 1.317 contratos de compras públicas federais, 255 processos judiciais americanos, 83 extratos bancários e os conjuntos de modelos . continua nenhum pintando texto em camada desligada. 106 declaram conteúdo opcional (2,9%), 7 têm grupo desligado por padrão (0,19%) e 7 trazem/AS(0,19%). O corpus de compras públicas deu zero em todas as linhas: nenhum dos seus 1.317 documentos declara conteúdo opcional, que é o que geradores de relatório fazem: camada vem de ferramenta de design. -
O motor classifica como alto risco um contrato normalmente
assinado por duas partes, e esse é o maior falso positivo que já
medimos. Rodado em 1.317 contratos de compras
públicas federais publicados no PNCP (baixados em
07/08/2026, motor 1.29.0, 0 ilegíveis): 89,8%
low, 0,4%elevated, 9,8%high. O agregado nos favorece, é melhor que as duas amostras acima, e esconde a história inteira, então segue a separação que importa:
sem assinatura 1.150 docs → 1.146 low, 4 elevated, 0 high
assinados 167 docs → 37 low, 1 elevated, 129 high
Em documento sem assinatura o motor dá 99,65% low. Em documento assinado, 77% dão high. Todos os 37 assinados que deram low têm exatamente uma revisão, ou seja, o gatilho não é adulteração, é a segunda assinatura.
O mecanismo não é um defeito, e é por isso que está divulgado aqui em vez de corrigido em silêncio. Quando a segunda parte assina, os bytes dela ficam além do/ByteRangeda primeira, entãosignature-coveragereporta emhighque as assinaturas não cobrem mais o arquivo; cada assinatura é uma revisão incremental, entãoincremental-updatesreporta emhigh; e/ID[1]tem de mudar a cada revisão, entãoid-inconsistencyreporta emmedium. Toda afirmação é verdadeira sobre os bytes. Enquanto isso,signature-integrityreportainfo: as assinaturas estão íntegras e o conteúdo assinado nunca foi alterado. O mesmo relatório diz que as assinaturas são válidas e dá nota 100 ao documento.
Um contrato assinado por duas ou mais partes é o documento legítimo mais comum deste mercado, e hoje o motor o trata como sua saída de maior risco. Até isso ser recalibrado, e é mudança de severidade, então espera a medição acima em vez de vir antes dela, leia uma faixahighem PDF com múltiplas assinaturas como não informativa. As famílias para ler no lugar sãosignature-integrity, que é a que de fato confere o digest, esignature-permissions. -
Metadado de imagem se apaga em um comando.
exiftool -all=remove toda identidade e todo carimbo de tempo que o motor de imagem encontra. Uma coincidência é evidência forte; uma ausência não é evidência nenhuma, e todo achado de imagem diz isso no próprio texto. -
O motor de Office não renderiza o documento. Texto
escondido por estar na cor do fundo, com tamanho zero, ou coberto por
uma forma não é detectado lá. A passagem de ordem de pintura que faz
a
redaction-exposurefuncionar ainda não tem equivalente em OOXML. É o maior buraco no meio mais novo, e ele é declarado em todo laudo de Office em vez de ficar subentendido. - PDF criptografado é declarado, não atacado. Um arquivo protegido por senha é reportado como “não analisado no conteúdo”, e não varrido como texto cifrado e reportado como limpo.
high é a segunda assinatura.
Todos os 37 assinados que deram low têm exatamente uma
revisão, ou seja, o gatilho não é adulteração. Até isto ser recalibrado, leia
uma faixa high em PDF com múltiplas assinaturas como não
informativa, e leia no lugar
signature-integrity
e
signature-permissions.
O número que ninguém neste mercado publica
O cenário concorrente foi lido diretamente em 31 de julho de 2026: Resistant AI, Inscribe, Snappt, Ocrolus, Truv, Veryfi, DocuClipper, VerifyPDF e HTPBE. Vários publicam um número de acurácia na casa dos 99% sem metodologia publicada, sem denominador declarado e sem verdade de referência, e é por isso que nenhum desses números é repetido aqui.
Nenhum deles publica com que frequência o sistema aponta um documento legítimo. Essa ausência é a razão de esta página existir. Não é uma afirmação de que nosso motor é melhor que os deles: vários fazem coisas que este não faz, numa escala para a qual este não foi construído. É uma afirmação sobre o que dá para conferir. Um número de detecção sem denominador não se discute, só se acredita; uma taxa de falso positivo sobre uma população pública, nomeada e não curada pode ser reproduzida por qualquer um que baixe os mesmos manifestos.
Vale para o mercado brasileiro em particular: o concorrente mais próximo daqui tem centro de gravidade em consulta de base de dados, e uma taxa de erro sobre documento legítimo é justamente o que a área de risco precisa para dimensionar quanta revisão manual um fluxo vai gerar.
Também não existe um teste independente a que qualquer um deste mercado pudesse se submeter. Não existe benchmark público de forense de estrutura de PDF: tabelas de referência cruzada, revisões incrementais, metadado de produtor, cobertura de assinatura. Os benchmarks acadêmicos são forense de imagem em nível de pixel, que é outro problema. Isso corta para os dois lados, e as duas metades sustentam peso: ninguém consegue provar que somos piores que o mercado, e nós não conseguimos provar que somos melhores. É por isso que esta página publica medições reproduzíveis do nosso próprio erro, e não um ranking que ninguém tem como rodar.
O que fazer com esta página. Rode pelo verificador gratuito um documento cuja resposta você já conhece (sem conta, nada é armazenado), e compare o que ele diz com as taxas acima. Depois leia o que cada família de sinal realmente olha e como o serviço é construído e operado, que é a outra metade de uma análise de fornecedor.
As fontes de cada número desta página são arquivos versionados no
repositório do produto: as notas de release do motor em
CHANGELOG.md (1.17.0, 1.18.0, 1.19.0, 1.22.0, 1.23.0,
1.27.0), a seção “Honest gaps” do STATUS.md, os agregados
de fase 0 versionados em docs/CORPUS-PHASE0-*.md e
docs/GLYPH-PHASE0-2026-08-05.md para as medições que
falharam, e a compilação de evidências em
docs/EVIDENCE.md §5.2, §5.3 para a leitura de
mercado acima. Achados por documento não são publicados: as regras do
corpus apagam os arquivos depois da rodada, e publicar uma lista de nomes
de arquivo de organizações ao lado de uma faixa de risco não é algo de
que uma medição precise.