# Hermes Documental — Lições Aprendidas

Updated: 2026-07-21

Este ficheiro regista conclusões verificadas em revisão humana e incidentes live.
Não altera diretamente o agente: cada lição que implique comportamento novo deve
seguir o processo revisão humana → lição documentada → instrução/pipeline versionado
→ golden-set → validação → produção.

## Intake WhatsApp — identidade `@lid` e fail closed

### Evidência observada

- Incidente live: `Hydra_iT_-_Fatura_FV2600103.PDF`.
- O primeiro agente recebeu `channel_intake_sender_invalid` porque a identidade do
  remetente tinha sido derivada do display name e, depois da rejeição, contornou o
  fluxo de intake já documentado.

### Lição e regra corretiva

- Uma rejeição de identidade é uma falha de autorização/routing, não autorização
  para tentar outro pipeline. Falhar fechado e usar sempre `sibyla-channel-intake`
  como primeira e única via para documentos recebidos por canal.
- Nunca contornar a rejeição recorrendo a OCR, Excel, Nextcloud,
  `documental-agent` ou outro fallback de processamento documental.
- Para WhatsApp, se o identificador `@lid` for rejeitado, só repetir o intake com
  um alias confiável fornecido por `gateway.whatsapp_identity`. Preservar o LID
  original em `trusted_metadata`; nunca construir o alias a partir do display name,
  texto da mensagem, nome do ficheiro ou conteúdo do documento.
- Se não existir alias confiável, terminar com erro acionável sem carregar ou
  processar o documento por outra via.

### Critério de regressão

- Um caso WhatsApp `@lid` rejeitado deve provar que não há chamada a OCR, Excel,
  Nextcloud ou `documental-agent`; havendo alias confiável, a única repetição usa
  esse alias e mantém o LID original em `trusted_metadata`.

## PDF sem text layer — fallback visual indisponível para o formato entregue

### Evidência observada

- Documento `af669e3b-606d-4bf1-93ee-1945b01a046f`, ficheiro
  `Brasileiro de Pereiro - FT. 1A2603.544.pdf`.
- A base de dados mostra o documento em `NeedsAttention`. O job
  `ExtractDocument` terminou com sucesso técnico porque persistiu uma revisão de
  erro; isto não significa que a extração documental tenha sido bem-sucedida.
- A revisão registou `readingMode = Vision` e os warnings
  `TEXT_LAYER_ABSENT_VISION_USED` e `UNREADABLE_AFTER_VISION`.
- O PDF não tem text layer e o `PdfTextExtractor` devolve `{status:unusable}`. É um
  PDF de uma página que contém uma única imagem JPEG, com 826 × 2741 píxeis, criada
  por iOS Quartz.
- Um render manual para PNG confirmou conteúdo visível e legível de
  fatura/recibo. Logo, a causa raiz não é ilegibilidade do documento: o fallback
  visual entregou ao Hermes um caminho de PDF que a capacidade visual disponível
  não aceitava diretamente.

### Lição e regra corretiva

- Ausência de text layer continua a não ser prova de ilegibilidade. Antes de chamar
  o Hermes, o pipeline deve pré-renderizar PDFs textless em imagens de página com
  limites explícitos, ou disponibilizar uma ferramenta igualmente bounded que
  forneça evidência visual num formato aceite pela capacidade visual.
- `UNREADABLE_AFTER_VISION` só é válido quando existe evidência de que a leitura
  visual recebeu e tentou efetivamente um formato suportado; uma incompatibilidade
  de formato/capacidade é erro de pipeline/runtime, não erro de legibilidade.
- Depois da correção, reprocessar de forma segura com uma correlation nova,
  persistir uma nova revisão que identifique a revisão anterior como superseded e
  preservar a revisão de erro e a auditoria existentes.

### Critério de regressão

- Adicionar este padrão ao golden-set: PDF textless de uma página com imagem
  legível. O teste deve provar render bounded, evidência visual consumível pelo
  Hermes e reprocessamento com correlation nova e relação de supersession, sem
  sobrescrever revisões anteriores.

### Implementação no pipeline

- Quando a extração textual falha, o mesmo helper PDF restrito tenta materializar
  uma imagem PNG ou JPEG por página para PDFs image-backed. A evidência fica em
  `input/visual` dentro da raiz transitória do job; o prompt aponta para essas imagens,
  não para o PDF, e disponibiliza apenas o toolset `vision`.
- O estágio visual está limitado a quatro páginas/imagens, 20 MiB de imagens e
  20 milhões de píxeis no total. Mais páginas são explicitamente tratadas como
  evidência truncada e obrigam a falhar fechado se não for possível estabelecer
  completude.
- PDFs corruptos, acima dos limites ou cuja composição não possa ser convertida
  com segurança pelo helper (por exemplo, páginas vector-only) mantêm o fallback
  anterior baseado apenas no caminho, sem colocar bytes ou texto do documento no
  prompt e sem fabricar conteúdo visual.
- As regressões automatizadas provam tanto PNG/Flate como JPEG/DCT consumíveis pelo
  Hermes; a regressão multipágina prova o limite e a instrução de truncation.
