# Baseline PaddleOCR-VL — 2026-08-25

Corpus de desenvolvimento: 30 scans ja expostos. Gabarito lido de producao apenas por `SELECT` e
transferido por pipe efemero; sem valores pessoais em ficheiros ou output. Holdout nao executado.
Sem fallback para Tesseract.

| Campo | Tesseract erros/vazios | PaddleOCR-VL erros/vazios |
|---|---:|---:|
| nome | 0 / 0 | 0 / 0 |
| ncc | 1 / 9 | 0 / 18 |
| validade_cc | 0 / 4 | 0 / 17 |
| nascimento | 0 / 0 | 0 / 0 |
| niss | 1 / 10 | 0 / 25 |
| filho_de | 4 / 3 | 0 / 17 |
| iban | 0 / 0 | 0 / 3 |
| naturalidade | 1 / 9 | 2 / 7 |
| concelho | 0 / 3 | 0 / 2 |
| distrito | 0 / 3 | 0 / 2 |
| nacionalidade | 0 / 4 | 0 / 0 |
| especialidade | 5 / 0 | 2 / 0 |
| val_vig | 0 / 4 | 0 / 2 |
| val_spr | 1 / 1 | 0 / 1 |
| val_ard | 1 / 3 | 0 / 2 |
| val_are | 0 / 3 | 0 / 1 |
| val_outro | 0 / 1 | 0 / 0 |
| val_rc | 0 / 1 | 4 / 0 |
| **Total** | **14 / 58** | **8 / 97** |

Tempos: Tesseract media 40090 ms, p95 83156 ms; PaddleOCR-VL media 18733 ms, p95 29532 ms.

Veredicto: passa velocidade e erros totais; reprova vazios totais e os gates por campo em
`naturalidade` e `val_rc`. Os valores errados ainda precisam de auditoria para distinguir imagem,
prompt, transcricao e parser; nao foi afirmada ausencia de fabricacao.

## Afinacao posterior à baseline

A tabela acima permanece imutável como ponto de comparação.

- `val_rc`: removido o fallback inseguro para a maior data; mantidas duas leituras focadas, recorte
  inferior e consenso. A validação adicional pelos 90 dias foi ensaiada e rejeitada porque o
  Paddle não transcreve a data de emissão no texto geral.
- `naturalidade`: o recorte focalizado foi ensaiado nos scans 12/18 e depois nos 30 casos. Rejeitado:
  as respostas focadas não continham o rótulo e o campo ficou vazio em todos os scans.
- A configuração rejeitada mediu 2 erros/150 vazios, média 26501 ms e p95 38551 ms. A redução de
  erros não compensa a perda de 56 campos; o fluxo operacional foi reposto no consenso anterior.

Nenhum destes ensaios conta fallback Tesseract como resultado VLM. O holdout permanece bloqueado.

## Lote dos vazios — 2026-08-25 (noite), ACEITE

Alteracoes so no cliente PHP (normalizacao VLM->parser, consenso de documento do NISS, banding
adaptativo em 2.a chamada para cartoes pobres, guarda de locale). API e modelo intocados. A regua
de comparacao e o run de diagnostico do proprio dia com o codigo pre-lote (5 erros/111 vazios —
difere da tabela imutavel acima porque a afinacao RC trocou 3 erros de val_rc por 14 vazios).

| Campo | Pre-lote erros/vazios | Lote erros/vazios |
|---|---:|---:|
| niss | 0 / 25 | 0 / 14 |
| filho_de | 0 / 17 | 0 / 14 |
| ncc | 0 / 18 | 0 / 17 |
| validade_cc | 0 / 17 | 0 / 17 |
| **Total (18 campos)** | **5 / 111** | **5 / 96** |

Zero erros novos em qualquer campo. Tempos: media 32,5 s / p95 49 s por scan (duas chamadas a API
nos scans com cartoes pobres; Tesseract: 40,1/83,2 s). Descoberta central: o Paddle quase nao
transcreve fotos de cartoes INTEIRAS (mediana 84-88 chars vs 1448 no RC), mas le bandas recortadas
das mesmas imagens — dai o banding adaptativo. Regras de seguranca: bandas so preenchem campos
vazios, com o mesmo valor em >=2 leituras (o atalho Luhn-em-leitura-unica deixou passar um NCC
errado no scan 21 e foi removido); texto truncado (eval_count>=1400) perde os campos-alvo e nao
confirma nada.

Nota operacional: em runs continuos de 30 scans ha ~1 falha transitoria por timeout (35 s) com a
GPU quente; o scan falhado passa isolado. Frente do CC continua quase ilegivel para o Paddle —
ncc/validade_cc sao o alvo da proxima fase (lado API: opcoes por tipo, prompts focados).
