feat(q1): E - B-3 preflight text too short, quarantine direct
Étape E du sprint Q-1 — B-3 pré-flight.
Si extract_text_with_fallback_ocr retourne moins de SEUIL_TEXTE_MINI
(=100) caractères :
- log.warning systématique
- Si quarantine_mgr fourni : flag preflight_text_too_short (severity=full),
copie du PDF original dans quarantine_dir/ pour ré-essai manuel
- Return {} (pas de sortie texte/audit/PDF pour ce doc)
Couvre les cas : scan non-OCRisé, PDF vide, OCR raté.
Évite le pire scénario : un opérateur qui croit que son document est
anonymisé alors qu'aucune PII n'a même été détectée parce qu'il n'y
avait pas de texte à traiter.
Rétro-compat préservée : sans quarantine_mgr, le comportement reste
"return {}" + log au lieu du silence (toujours strictement meilleur).
Risque appelants : un caller qui suppose la présence des clés "text"/
"audit" dans le retour doit gérer le cas dict vide. À voir au runtime.
Ref: docs/coordination/inbox/for-dom/2026-05-29_consolide_pseudocode-Q1-v2.md §8
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4279,6 +4279,30 @@ def process_pdf(
|
||||
cfg = load_dictionaries(config_path)
|
||||
pages_text, tables_lines, ocr_used, ocr_word_map = extract_text_with_fallback_ocr(pdf_path)
|
||||
|
||||
# Q-1 B-3 : pré-flight texte vide. Si moins de SEUIL_TEXTE_MINI caractères
|
||||
# extraits, c'est probablement un scan non-OCRisé ou un document corrompu.
|
||||
# On NE traite PAS — quarantaine totale, le doc original est copié pour
|
||||
# ré-essai manuel.
|
||||
extracted_chars = sum(len(p) for p in pages_text)
|
||||
if extracted_chars < SEUIL_TEXTE_MINI:
|
||||
log.warning("Preflight failed for %s: only %d chars extracted (seuil=%d)",
|
||||
pdf_path.name, extracted_chars, SEUIL_TEXTE_MINI)
|
||||
if quarantine_mgr is not None:
|
||||
quarantine_mgr.flag(
|
||||
doc_name=pdf_path.stem,
|
||||
reason="preflight_text_too_short",
|
||||
detail=f"Only {extracted_chars} chars extracted from {len(pages_text)} pages (seuil={SEUIL_TEXTE_MINI})",
|
||||
severity="full",
|
||||
extracted_chars=extracted_chars,
|
||||
)
|
||||
try:
|
||||
quarantine_mgr.quarantine_dir.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy(pdf_path, quarantine_mgr.quarantine_dir / pdf_path.name)
|
||||
except Exception as copy_err:
|
||||
log.warning("Could not copy original PDF to quarantine for %s: %s",
|
||||
pdf_path.name, copy_err)
|
||||
return {}
|
||||
|
||||
# 1) Regex rules + NER-first cross-validation
|
||||
# Passer les NER managers pour que anonymise_document_regex exécute le NER
|
||||
# sur le texte original (non masqué) et valide les noms extraits par regex
|
||||
|
||||
Reference in New Issue
Block a user