QualityValidator.validate_entry() detectava PLACEHOLDER_MISMATCH mas só
revertia para o msgstr original — se a entrada já chegasse corrompida
(de fora do pipeline, ou de execuções anteriores do LibreTranslate), o
bug ficava preservado silenciosamente em vez de corrigido.
Adiciona repair_placeholders(), chamado no início de validate_entry():
- '%1$s' -> '% 1$s' (espaço após % antes do posicional) -> reparado
- '%1$.2f' -> '% 1$. 2f' (espaço após o ponto decimal) -> reparado
Âncora obrigatória: \d+\$ (posicional). Nunca ocorre em prosa PT-PT,
por isso zero falsos positivos em texto legítimo (testado contra '50%
do total', '30% em vendas', etc. — ficam inalterados).
Testado contra as 4 strings reais encontradas corrompidas em produção
(testimonial-pro, woocommerce, wordfence, wp-optimize) — todas reparam
para o valor correcto exacto.
Causa raiz: motor LibreTranslate (TranslationEngine.translate) recebe
placeholders crus, sem tokenização — ao contrário de translate_missing.py
(DeepL) que protege com tokens ⟦N⟧. Reparação aqui é mitigação; a
tokenização do motor LibreTranslate fica como follow-up.
Normalizacao OKF dos .md: type/title/description/timestamp/layer +
descriptions factuais (rich abstracts). Apenas .md tracked; corpos intactos.
Parte da aplicacao OKF a /Dados/Dev (28-06-2026).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Verificação de integridade ao conectar (PRAGMA integrity_check)
- Validação de esquema completo (4 tabelas, todas as colunas)
- Migração automática de colunas em falta
- Tabela translation_backups para guardar originais antes de traduzir
- CLI --verify-db e --restore-backup
- WAL mode para melhor concorrência
Tarefa #419, Discussão #33, Projecto #65