# 04 — Política de confiança por campo, com casos de teste

Expansão da tabela de PLANO.md ("Política de confiança por campo") com casos de teste concretos, incluindo negativos. Critério global mantido do plano: **zero valores errados com confiança alta** no conjunto de validação.

## 1. Tabela-base (do plano, para referência)

| Campo | Confiança alta exige | Fonte 2 | Qwen |
|---|---|---|---|
| NIF, NISS, IBAN, nº CC | Formato + checksum + rótulo/posição certos + titular coerente | Verso do CC / MRZ | Não |
| Validade CC | Data a seguir a "Data de validade"/"Expiry" | MRZ do verso | Não |
| Cartão PSP | Número = MAI 6 dígitos + sufixo coerente + validade no mesmo bloco + titular = CC | — | Só se número ilegível |
| RC (val_rc, finalidade) | "CÓDIGO VIGENTE ATÉ" + finalidade correta + titular | — | Sim (independente) |
| Nome, nascimento, naturalidade | CC frente/digital com rótulo | RC | Sim, se divergência |
| Morada | Fonte identificada + normalização ao padrão da casa | CC digital vs comprovativo vs portal | Sim: comparador semântico |
| Zona, local, horas, alínea, modalidade | Lista do utilizador | — | Não |
| Contacto, email, emergência | Portal dos dados | — | Não |
| Conferência pós-inserção | SELECT comparado com manifesto/documentos | — | Sim: equivalência semântica |

## 2. Calibração da escala de confiança (herdada do SKILL.md, reutilizada aqui)

- **100**: nítido e confirmado por segunda fonte (checksum, cruzamento portal/CC, MRZ vs frente) OU campo importado do portal dos dados (fonte digital direta, sem incerteza de leitura).
- **90-99**: nítido mas sem confirmação independente (ex. `filho_de`, naturalidade sem RC a confirmar).
- **70-89**: legível com dúvida (scan fraco, abreviatura interpretada) → vai para revisão.
- **<70**: ilegível/adivinhado → revisão + marcado "incerto".
- Checksum falhado nunca sobe de 50, por muito nítido que o documento esteja.

## 3. Casos de teste por campo

### NIF / NISS / IBAN / nº CC

| Entrada | Confiança esperada | Motivo |
|---|---|---|
| NIF nítido, checksum mod-11 OK, rótulo "NIF" ao lado | 100 | Formato + checksum + posição certos |
| NIF nítido mas checksum mod-11 falha | ≤50 | Checksum falhado nunca sobe de 50 |
| NISS com um dígito pouco legível, checksum OK (fórmula 29,23,19,17,13,11,7,5,3,2) | 85-90 | Legível com dúvida mas checksum confirma — REVER, valor exposto com o motivo |
| IBAN PT transcrito com reagrupamento errado (falso "inválido") | Revisão obrigatória antes de reportar falhado — reler o documento primeiro | Regra explícita da skill: 3 falsos "IBAN inválido" por reagrupamento em 2026-09-15 |
| IBAN estrangeiro válido (ISO 13616), sem checksum automático | 90-99 (nítido, sem confirmação independente) | Checksum mod-97 só se aplica a PT50 |
| Nº CC (Luhn sobre os 12 caracteres) falha | ≤50, nunca gravado sem correção | Luhn sobre o número completo, nunca o check ICAO da MRZ |

### Validade CC

| Entrada | Confiança esperada | Motivo |
|---|---|---|
| Data clara a seguir a "Data de validade", MRZ do verso confirma | 100 | Segunda fonte (MRZ) confirma |
| Data clara mas verso não disponível/não lido | 90-99 | Nítido, sem confirmação independente |
| Data com mancha/brilho, valor só parcialmente legível | 70-89 | Revisão, evidência via `[img]` |
| CC digital (app gov.pt) com formato dd-mm-aaaa vs CC físico dd mm aaaa | Tratar formatos distintos sem confundir dia/mês | Regra validada no `RESULTADOS-2026-09-22.md` |

### Cartão PSP (nº, categoria, validade)

| Entrada | Confiança esperada | Motivo |
|---|---|---|
| Nº = MAI (6 díg.) + sufixo 05x, categoria impressa "Ass. Recinto Desportivo", validade no mesmo bloco, titular = nome do CC | 100 | Tudo coerente |
| Sufixo do nº (04x) não bate com a categoria impressa (ex. impressa como ARD) | Bloqueia/revisão — reler a imagem antes de gravar | Regra do caso real 773: troca de validade ARD/ARE só apanhada porque o utilizador perguntou |
| Nº ilegível (png baixa resolução), categoria pelo texto impresso | Confiança reduzida, Qwen entra como segunda leitura independente (único caso em que o Qwen lê cartões) | "Qwen: só se número ilegível" |
| Cartão de especialidade presente na pasta mas sem vínculo confirmado | Não gravar como especialidade automaticamente | Achado do teste de 22/09: 9 processos com cartões na raiz sem vínculo real |
| Titular impresso no cartão diferente do nome do CC | Bloqueado, reportar | Regra "titular = nome do CC" |

### RC (registo criminal)

| Entrada | Confiança esperada | Motivo |
|---|---|---|
| "CÓDIGO VIGENTE ATÉ" claro, finalidade "exercício da atividade de segurança privada" presente, Qwen confirma independentemente | 100 | Documento difícil + segunda fonte independente + confirmação Qwen |
| Data de emissão usada em vez de "vigente até" | Erro a bloquear na Fase A (checklist obrigatória) | Erro real documentado nos 2 primeiros dry-runs |
| Finalidade ausente ou diferente ("outra finalidade") | **Bloqueado** — certificado não serve, não usar campos sem OK explícito | Regra explícita do SKILL.md |
| RC caducado (`val_rc` no passado à data da consulta) | **Bloqueado** — pede sempre decisão humana, mesmo que já tenha sido autorizado noutros casos | "Pergunta-se sempre" (modo lote, ponto 4) |
| RC formato novo sem "NATURAL DA FREG."/concelho | `naturalidade="Portugal"`, `concelho`/`distrito` em branco sem penalizar confiança | Limitação do documento, não da leitura |
| Qwen afirma equivalência semântica ("RC é da mesma pessoa apesar do nome truncado") mas a comparação literal falha | Aparece como "equivalente segundo o modelo" na tabela, entra na estatística de fiabilidade | Princípio 2 do plano: Qwen nunca decide sozinho |

### Nome, nascimento, naturalidade

| Entrada | Confiança esperada | Motivo |
|---|---|---|
| Nome no CC com rótulo claro, RC confirma o mesmo nome | 100 | Segunda fonte (RC) |
| Nome só no CC, sem RC para confirmar | 90-99 | Nítido, sem confirmação independente |
| Divergência de nome entre CC e RC (abreviatura/acento) | Qwen entra como comparador semântico; se confirmar equivalência, registar como tal; se não, revisão | "Sim, se divergência" |

### Morada

| Entrada | Confiança esperada | Motivo |
|---|---|---|
| Morada igual em CC digital, comprovativo e portal, já no padrão da casa após normalização | 100 (fonte identificada + normalização) | Múltiplas fontes concordam |
| Morada só na certidão AT, sem comprovativo | 90-99, fonte declarada no relatório | Prioridade CC/certidão AT > fatura > portal |
| Duas moradas diferentes em documentos oficiais (ex. RC/AT vs fatura de banco) | **Bloqueado** — perguntar ao utilizador; portal pode desempatar mas não decide sozinho | Caso real 804: Grijó vs Sta. Maria de Lamas |
| Morada escrita de forma diferente nas duas fontes mas é a mesma rua (abreviatura, ordem) | Qwen como comparador semântico confirma equivalência; se rejeitar, fica revisão | "Comparador semântico: é a mesma morada escrita de outra forma?" |
| Ficheiro "comprovativo de morada" que na prática é outra coisa (fatura EDP, carta verde de seguro) | Usar a morada que lá está, mas declarar a fonte real no relatório | Achado de ~30 pastas reais |

### Zona, local, horas, alínea, modalidade

| Entrada | Confiança esperada | Motivo |
|---|---|---|
| Valor vem diretamente da lista dada pelo utilizador | Alta por definição (fonte = utilizador, não há "leitura" a avaliar) | "Lista do utilizador" |
| Zona escrita de forma ambígua (ex. "Porto" sem indicar qual) | Resolver pela `clientes.zona` do local antes de perguntar | Regra do modo lote |
| Horas calculadas (dias × horário) em vez de dado direto | Perguntar sempre os dias e horário deste cliente concreto, nunca reutilizar cálculo doutro caso | Erro real: 56H assumidas por analogia, horário real era 60H |

### Contacto, email, emergência

| Entrada | Confiança esperada | Motivo |
|---|---|---|
| Vem do portal dos dados | 100 | Fonte digital direta — regra explícita do plano ("TODOS os campos importados do portal") |
| Candidato não respondeu no portal | Vazio, não inventar | — |

### Conferência pós-inserção (todos os campos)

| Entrada | Resultado esperado | Motivo |
|---|---|---|
| SELECT ao Sabichão bate literalmente com o manifesto | `certo`, alimenta `fichas_fiabilidade` | Comparação literal OK |
| SELECT diverge só na forma (acentos, abreviatura da morada) | Qwen confirma equivalência semântica → `equivalente_semantico_confirmado` | Uso do Qwen como comparador, não como fonte |
| SELECT diverge mesmo na substância (valor realmente diferente) | `errado`, discrepância fica visível no caso | Nunca silenciar |

## 4. Casos negativos (obrigatórios no golden dataset, ver 05-GOLDEN-DATASET.md)

| Caso negativo | Comportamento esperado |
|---|---|
| Documento errado (RC/IBAN de outra pessoa na pasta) | Bloqueado — tratar como documento em falta, nunca usar em silêncio (casos reais 795, 796) |
| RC caducado | Bloqueado — pergunta sempre, mesmo com histórico de autorização noutros casos |
| RC sem finalidade de segurança privada | Bloqueado — certificado não serve |
| Morada divergente entre fontes oficiais | Bloqueado — pergunta ao utilizador, portal só desempata |
| Número de cartão PSP ilegível | Qwen como segunda leitura; se ainda assim ilegível, revisão obrigatória, nunca adivinhar |
| Cartão com sufixo que não bate com a categoria impressa | Reler antes de gravar; se persistir, revisão |
| CC digital vs físico | Formatos de data distintos tratados corretamente (dd-mm-aaaa vs dd mm aaaa), sem confundir |
| Re-admissão (NIF `Desativo` existente) | Ramo próprio: herda campos do processo anterior conforme 24m de reuso, nunca tratado como erro de input |
| NIF `Ativo` inesperado (não é re-admissão) | Bloqueado — erro de input, parar |
| Pasta do processo sem imagens/PDFs (caso real 777) | Bloqueado — nada para ler |

A CONFIRMAR: limiares numéricos exatos de confiança para cada transição de estado no motor (ex. "abaixo de 90 vai para `por_rever`") — o plano define a calibração geral (100/90-99/70-89/<70) mas não fixa qual desses patamares corresponde exatamente ao corte entre "alta" e "revisão" para efeitos da máquina de estados; assumir aqui que `<90` (ou seja, fora do patamar 100) entra em revisão, alinhado com "Campos a 90+ não se listam um a um" do SKILL.md, mas confirmar com o utilizador antes da Fase 2.
