fix(detect): F5 — masque la continuation orpheline d'un nom composé (EJNAINI)
Dernière fuite de l'audit_30. Cas Trackare : un nom composé "NOCENT-EJNAINI"
éclaté en colonnes devient "[NOM]-\nEJNAINI" — le 1er composant est masqué
par le NER mais le 2e reste en clair (ni span NER intact ni candidat regex ne
le couvre ; être dans paranames ne suffit pas sans candidat).
Fix : post-passe dans process_pdf (étape 3a-bis), après selective_rescan, qui
masque le token majuscule orphelin suivant immédiatement un "[NOM]-". Couvre
le texte ET le raster (NOM_GLOBAL). Réfute la conclusion de Qwen ("paranames
résoudra EJNAINI").
Validation audit_30 (29 docs) : score 98.3 → 98.5/100, LEAK SCORE 100/100
(0 fuite), 0 régression FP. tests/unit 85 passed. BA127127 : EJNAINI 7→0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
---
|
||||
from: claude
|
||||
to: dom
|
||||
date: 2026-06-03
|
||||
topic: ejnaini-root-cause (T-H)
|
||||
status: RÉSOLU — fix F5 implémenté + validé audit_30
|
||||
references:
|
||||
- file: docs/coordination/inbox/for-dom/2026-06-02_qwen_ejnaini-investigation.md
|
||||
- doc: trackare-BA127127-23135726
|
||||
---
|
||||
|
||||
# EJNAINI — cause racine confirmée (et conclusion de Qwen corrigée)
|
||||
|
||||
## Test empirique (moteur actuel, paranames + stopwords nettoyés)
|
||||
|
||||
Re-traitement du PDF source `433_23135726/trackare-BA127127...pdf` :
|
||||
|
||||
| Token | Avant | Maintenant |
|
||||
|---|---|---|
|
||||
| `NOCENT` | 7 fuites | **0** ✅ |
|
||||
| `EJNAINI` | 7 fuites | **7** ❌ |
|
||||
|
||||
Pattern résiduel **déterministe** (7×) :
|
||||
```
|
||||
[NOM]-
|
||||
EJNAINI
|
||||
```
|
||||
|
||||
## Conclusion de Qwen RÉFUTÉE
|
||||
|
||||
Qwen concluait : « paranames résoudra EJNAINI ». **Faux.**
|
||||
- `EJNAINI` **est** dans paranames (`noms_famille_world.txt.gz`) et chargé dans le core (vérifié).
|
||||
- Il reste pourtant non masqué.
|
||||
|
||||
## Vraie cause racine
|
||||
|
||||
Deux chemins de masquage parallèles dans le moteur :
|
||||
1. **Spans NER** → remplacement direct du span détecté. Capte `Cécilia NOCENT-EJNAINI` **là où il est intact** (166 hits NOM).
|
||||
2. **NameCandidates** (regex) → cross-validation (NER/INSEE/paranames) → `safe_names` → remplacement global **+ redaction raster** (`NOM_GLOBAL`).
|
||||
|
||||
En zone tableau Trackare, le nom est éclaté sur deux lignes : `NOCENT-` en fin de ligne, `EJNAINI` orphelin plus bas.
|
||||
- Le span intact `Cécilia NOCENT-EJNAINI` n'existe pas → chemin 1 ne le voit pas.
|
||||
- Aucun candidat regex ne propose `EJNAINI` seul → chemin 2 ne le voit pas (donc paranames jamais consulté pour lui).
|
||||
- F1 ne décompose que les tokens **uniques** à trait d'union déjà dans `names`, pas les **spans multi-mots** NER.
|
||||
|
||||
`NOCENT` finit masqué (`[NOM]-`) par un autre artefact de remplacement, mais `EJNAINI`, n'étant ni dans un span intact ni dans `safe_names`, fuit.
|
||||
|
||||
## Fix recommandé (robuste, corrige texte ET PDF)
|
||||
|
||||
Quand le NER détecte un nom **multi-mots ou à trait d'union** (PER), **décomposer** le span et injecter ses tokens composants (≥4 chars, non stop-word, confirmés gazetteer/NER) comme **NameCandidates haute confiance** → ils entrent dans `safe_names` → remplacement global + `NOM_GLOBAL` (raster).
|
||||
|
||||
C'est une généralisation de F1 aux spans NER multi-mots. Avantage : masque `EJNAINI` partout (texte + raster), pas un patch cosmétique sur le `.txt`.
|
||||
|
||||
## Fix implémenté (F5) — post-passe orpheline
|
||||
|
||||
Au lieu de la décomposition des spans NER (le span n'existe pas en zone tableau),
|
||||
la solution retenue cible directement le pattern résiduel : après `selective_rescan`,
|
||||
on masque le token majuscule orphelin qui suit immédiatement un `[NOM]-` (cas
|
||||
`[NOM]-\nEJNAINI`). Implémenté dans `process_pdf` (étape 3a-bis), même style que le
|
||||
nettoyage des codes postaux orphelins. Masque le texte **et** le raster (via `NOM_GLOBAL`).
|
||||
|
||||
## Validation (2026-06-03)
|
||||
|
||||
- BA127127 re-traité : `NOCENT=0, EJNAINI=0` ✅
|
||||
- `tests/unit` : 85 passed
|
||||
- **audit_30 complet** (29 docs, 1 quarantiné) :
|
||||
- **Score global 98.5/100 (A+)** (baseline 97.0, +1.5)
|
||||
- **Leak score 100/100** — 0 fuite audit, 0 regex, 0 INSEE contexte fort
|
||||
- FP score 95 (+5 vs baseline), 0 terme médical masqué
|
||||
- **Aucune régression**
|
||||
|
||||
EJNAINI était la dernière fuite de l'audit_30. **Leak score = 100%.**
|
||||
|
||||
— Claude
|
||||
|
||||
Reference in New Issue
Block a user