Commit Graph

25 Commits

Author SHA1 Message Date
890edb360e feat(cli): option --engines, diagnostic honnête des moteurs du build CLI
Axe CLI (intégration dans d'autres programmes) : contrat stable, codes retour
fiables. `--engines` liste les moteurs réellement disponibles dans CET
exécutable CLI (`[OUI]/[NON] Label (requis/optionnel) — raison`) et sort 0, sans
traiter. `input` devient optionnel pour ce mode (sinon code 2).

Le fail-closed CamemBERT (code 3) et le best-effort EDS/GLiNER (jamais déclarés
actifs si le chargement échoue) restent inchangés. Ne présume pas du build GUI.

2 tests (--engines → code 0 + moteurs listés ; absence d'input → code 2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 17:38:56 +02:00
873fd5622a build(gui): add Windows GUI V6 one-click packaging 2026-06-13 09:31:14 +02:00
fff4a2d902 fix(cli): avoid duplicate ONNX native load in Windows frozen 2026-06-12 16:49:11 +02:00
26f0cdfd68 feat(cli): add dedicated Inno Setup installer for the Windows CLI
Installateur Inno Setup séparé de la GUI (validé GO par Qwen), pour tests
internes et intégration de la brique CLI dans un autre logiciel.

- installer/Anonymisation-CLI.iss : AppId distinct de la GUI
  (B2F4A7C1-…), PrivilegesRequired=lowest, DefaultDirName
  {localappdata}\Programs\Anonymisation-CLI, source dist\Anonymisation-CLI.exe.
  Clés registre HKCU stables (InstallPath/ExePath/Version) + App Paths HKCU
  pour résolution tierce, supprimées à la désinstallation (uninsdeletekey).
  Pas de PATH système, pas de raccourci bureau. GUI .iss non modifiée.
- installer/Anonymisation-CLI-README.txt : usage, codes retour, lookup registre.
- scripts/build_windows_cli_installer_only.ps1 : build ISCC dédié,
  sortie release\Anonymisation-CLI-Setup.exe + SHA-256.
- docs/build-windows-oneclick.md : section « Installateur CLI dédié ».

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 16:44:58 +02:00
263126dafa feat(cli): add Windows single-file anonymization entrypoint
CLI de production sans GUI pour anonymiser un fichier unique, validé GO par
Qwen (revue indépendante contrat/packaging/modèles) sur de vrais PDF.

- scripts/anonymize_cli.py (NOUVEAU) : contrat positionnel
  `Anonymisation-CLI.exe <fichier> <dossier_sortie>` (+ --out compat),
  chemins espaces/accents, codes retour 0/1/2/3/4.
  Chargement modèles fail-closed : CamemBERT-bio ONNX OBLIGATOIRE (code 3 si
  absent, aucun mode dégradé silencieux) ; EDS-Pseudo + GLiNER optionnels,
  tracés au log ; --no-ner = regex seul assumé. Résolution _MEIPASS frozen
  alignée sur launcher.py. Sortie burn raster identique GUI v5.
- anonymisation_cli_onefile.spec : entrypoint basculé vers anonymize_cli.py
  (le harnais perf D-19 anonymize_batch_cli.py reste hors build).
- docs/build-windows-oneclick.md : section « CLI Windows (sans GUI) »
  (build, usage, codes retour, modèles, limitations).

Tests Linux (vrais PDF) : --help OK, fichier manquant→2, --no-ner accents→0,
NER complet→0 (CamemBERT-bio + EDS-Pseudo chargés), modèle déplacé→3.
Build/smoke Windows à suivre (séparé). Commit CLI-only strict, distinct du P0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 14:26:11 +02:00
21a408a9e4 fix(perf): apply MVP threading hotfix
Configure numerical library and torch threading for H1, keep raster threading/timing instrumentation, remove CONCERTATION from forced masks after real PDF FP testing, and record coordination archive state.
2026-06-08 10:41:15 +02:00
94233c3538 build(windows): scripts build one-click + installer + doc
- build_windows_oneclick.bat / build_windows_installer_oneclick.bat : wrappers
- scripts/build_windows_oneclick.ps1 / build_windows_installer_only.ps1 / install_inno_setup_build_dep.ps1
- build_signing.example.ps1 : exemple protocole signing (sans secret)
- docs/build-windows-oneclick.md : documentation du build

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 16:31:06 +02:00
ae73abe65d feat(T-I): validateur paranames + filtre mots-outils FR du gazetteer
Validateur scripts/validate_paranames.py exécuté sur le gazetteer réel,
révèle 2 défauts → corrigés :

- Mots-outils FR (avec/dans/voir/...) présents dans INSEE/paranames →
  risque FP au contexte 'low'. Ajout de 347 mots-outils spaCy fr (sûrs,
  filtrés des patronymes INSEE fréquents) à stopwords_manuels.txt.
  build_paranames_gazetteer.py filtre désormais aussi contre ce fichier ;
  gazetteer reconstruit (1 379 196 noms, mots-outils ≥3 chars retirés).
- Priorité sécurité respectée : allez/polygone sont de vrais patronymes
  INSEE rares → laissés MASQUABLES (pas de fuite), hors stopwords.
- OYARCABAL reclassé en warning (couvert par regex F3, absent de Wikidata).

Garde-fous vérifiés : Petit/Boucher/Berger conservés, noms étrangers
(EJNAINI/NGUYEN/...) conservés. Validateur 5/5. tests/unit 85 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 11:20:21 +02:00
745ebd93fb feat(detect): paranames gazetteer Wikidata (1.4M noms + 502K prénoms)
Intégration de paranames (bltlab/paranames v2024.05.07.0, CC BY 4.0)
pour étendre la couverture du gazetteer aux noms étrangers en France
absents d'INSEE (basques, maghrébins, asiatiques, africains, etc.).

## Citation

Sälevä, J., & Lignos, C. (2024). ParaNames 1.0: Creating an Entity Name
Corpus for 400+ Languages using Wikidata. In Proceedings of LREC-COLING
2024. https://aclanthology.org/2024.lrec-main.1103/

## Fichiers

- scripts/build_paranames_gazetteer.py — script reproductible
- data/paranames/README.md — attribution + procédure
- data/paranames/EXTRACTION.md — workflow reproductible
- data/paranames/noms_famille_world.txt.gz — 1 379 609 noms (4.3 Mo gz, <30 Mo RAM)
- data/paranames/prenoms_world.txt.gz — 502 302 prénoms (1.4 Mo gz)

## Volume final

Réduction significative vs estimation initiale (~80 Mo) grâce à NFKD+A-Z
qui fusionne toutes les translittérations Wikidata (cyrilliques, arabes,
chinoises…) en latin de base. Résultat : 4.3 Mo gz total, ~30 Mo RAM.

## Spot-check

| Nom | Présent ? | Note |
|---|---|---|
| EJNAINI |  | Le cas de fuite résiduelle audit_30 — devrait être fixé |
| OYARZABAL |  | Variante basque |
| OYARCABAL |  | Orthographe franco-espagnole rare, absente Wikidata |
| NGUYEN, SCHMIDT, OBAMA, NAKAMURA, GARCIA, MARTIN, BERNARD |  | OK |

## Intersection INSEE

- ∩ INSEE FR : 130 340 noms (59.5 % de couverture INSEE)
- Gain net : 1 249 269 noms supplémentaires (focus diaspora / DOM-TOM)

## Risque FP identifié

Quelques mots français courants sont présents dans paranames (origine :
noms d'autres langues) : VOIR, ALLO. MIDI déjà filtré par stopwords.
Impact à mesurer sur retraitement audit_30. Si nécessaire, ajout d'un
filtre dictionnaire français à apporter ultérieurement.

## Source

- Dépôt : https://github.com/bltlab/paranames
- Mirror HF (utilisé) : https://huggingface.co/datasets/imvladikon/paranames
- License : CC BY 4.0
- Origine : Wikidata (entités publiques) — pas de PII fuitée

REJETÉ comme alternative : philipperemy/name-dataset (origine = leak
Facebook 2021, RGPD bloquant pour produit médical).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-02 16:02:54 +02:00
bf268bac12 fix(scripts): reprocess_audit30 path local Dom (env override) (D-12 fixup)
L'agent CHCB cleanup a remplacé CHCB → CHUXX dans le path SOURCE_ROOT
mais le vrai dossier sur le disque Dom s'appelle bien
'II-1 Ctrl_T2A_2025_CHCB_DocJustificatifs (1)'. Ça a cassé toutes
les recherches PDF (29/29 MISSING).

Fix : lecture du path depuis env var ANON_AUDIT30_SOURCE avec fallback
sur le path local réel. Le nom CHCB est dans le path filesystem chez
Dom, pas une référence sémantique à anonymiser.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-02 14:47:09 +02:00
92557d4e74 chore(rgpd): replace CHCB/Bayonne/Saint-Denis/Réunion refs in source + configs (D-12)
Anonymise toutes les références à des entités réelles (CHCB, Bayonne, Saint-Denis,
Réunion, etc.) dans le code source, les configurations YAML, les scripts/outils,
et les tests unitaires. Conserve les tests synthétiques (cases) intentionnels.

- profile key chcb_strict → chuxx_strict
- CHCB → CHUXX, Bayonne → Chicago, Saint-Denis → Springfield,
  Réunion → Province Bêta, 64100/97400 → 12345, FINESS → 999999999,
  préfixe tél 05.59.44 → 0X.XX.XX
- renomme tools/test_chcb_leak.py → tools/test_force_term_leak.py

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-02 14:39:21 +02:00
2f96f56432 chore(scripts): add reprocess_audit30.py for quality regression testing
Petit utilitaire pour re-traiter le corpus audit_30 avec le code courant
et générer un dossier de sortie horodaté.

Usage:
    python scripts/reprocess_audit30.py [--out /tmp/.../foo] [--no-ner]

Lit la liste des 29 docs depuis evaluation/baseline_scores.json, retrouve
chaque PDF source dans /home/dom/Téléchargements/.../CHCB_DocJustificatifs,
appelle process_pdf() pour chacun, sortie dans /tmp/reprocess_audit30/
(ou --out).

Permet ensuite de mesurer la qualité avec :
    python scripts/evaluate_quality.py --dir <output> --compare

Validé sur audit_30 — 29 docs en ~4 min avec NER ONNX.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-02 14:26:02 +02:00
34dcf8f360 Externalize dictionaries and add anonymization review corpus 2026-04-21 10:32:57 +02:00
a1bf31c47f feat(gui): afficher version + build date + commit dans titre et status bar
Demande utilisateur : pouvoir identifier la build au premier coup d'oeil
sans confondre ancien/nouveau exe lors des tests.

Implémentation :
- build_info.py (gitignored, fallback "dev" pour mode développement)
  régénéré automatiquement par scripts/rebuild_anon.ps1 avec :
  BUILD_DATE = "2026-04-15 18:15"
  BUILD_COMMIT = "7665ef1"
  BUILD_BRANCH = "main"
- Pseudonymisation_Gui_V5.py : fonction _version_long() qui construit
  "v5.4 · 2026-04-15 18:15 · #7665ef1" depuis build_info (avec fallback
  silencieux si module absent en dev). Affichée dans :
    - Titre fenêtre : "Pseudonymisation de vos documents — v5.4 · ..."
    - Status bar en bas à droite
- anonymisation_onefile.spec : build_info.py ajouté aux datas bundlées.
- scripts/rebuild_anon.ps1 : STEP 4a génère build_info.py avant le
  PyInstaller avec git rev-parse short + branch + date courante.
- .gitignore : build_info.py exclu (volatile, regénéré).

En mode dev (pas frozen) : affichage "v5.4" seul (fallback).
En mode frozen : affichage complet avec date/commit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 18:40:58 +02:00
b724672b5a chore(rebuild): script PowerShell robuste — rename + verif timestamp
Après deux rebuilds Windows silencieusement échoués (PermissionError
WinError 5 lors du os.remove par PyInstaller), amélioration du script :

1. Renommer l'ancien Anonymisation.exe en Anonymisation.old-HHMMSS.exe
   AVANT le build (au lieu de laisser PyInstaller faire os.remove qui
   échoue si Defender tient un handle). Move-Item bypass la plupart des
   scanners antivirus.

2. Exclusions Defender sur dist/ et build/ (Add-MpPreference).

3. Retry Remove-Item avec délai 10s × 5 sur build/ en cas de lock.

4. Vérification timestamp APRÈS/AVANT : si l'exe final a le même
   LastWriteTime qu'avant le build, exit code 2 "ÉCHEC CRITIQUE —
   timestamp inchangé". Évite le faux OK quand le build rate mais que
   l'ancien exe subsiste.

5. Encodage UTF-8 BOM nécessaire pour PowerShell Windows (accents
   français dans les messages).

Validé : rebuild v5d a passé — nouveau exe 17:47:40 (vs ancien 17:09:32),
ancien renommé en Anonymisation.old-174023.exe.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 17:48:19 +02:00
89e1a16856 fix(finess): inclure les entjur + supprimer code mort _FINESS_ETAB_NAMES
Deux corrections exploitant mieux les gazetteers FINESS/INSEE pour réduire la
dépendance au YAML force_mask_terms.

1. scripts/build_finess_gazetteers.py : ne lisait que col 1 (finess_et) du CSV.
   Les col 2 (entjur, entité juridique) étaient ignorés. ~48k numéros
   juridiques manqués, dont 640780417 (CHCB entjur) forcé en YAML à cause
   de cette lacune. Fix : lecture col 1 + col 2 avec déduplication.
   Régénération : 101 941 → 150 436 numéros (+48 495).

2. anonymizer_core_refactored_onnx.py :
   - _FINESS_ETAB_NAMES (122k noms) chargé mais jamais consulté après le
     refactoring NER-first (le matching passe par l'Aho-Corasick sur
     etablissements_distinctifs.txt). Suppression → -122k entrées RAM.
   - _INSEE_PRENOMS (lowercase) et _INSEE_PRENOMS_SET (uppercase sans accents)
     lisaient deux fois le même fichier prenoms_france.txt. Fusion en une
     seule passe disque, les deux formes dérivées en mémoire. -36k lectures.

Validation :
- 640780417 présent dans _FINESS_NUMBERS après rebuild
- 122 hits sur trackare-18007562 (non-régression)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 09:33:07 +02:00
084f8a3246 docs: scripts de génération des fiches produit et technique DSI/RSSI/DPO
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 10:17:14 +02:00
5966ea7518 feat: export/import paramètres par email + script merge côté serveur
GUI :
- Bouton "Exporter pour envoi" → fichier JSON sur le Bureau avec
  whitelist + blacklist + version + date, prêt à envoyer par email
- Bouton "Importer" → charge un JSON et fusionne (sans doublons)

Serveur :
- scripts/merge_params.py : fusionne les JSON reçus des établissements
  dans la config maîtresse dictionnaires.yml
  Usage : python scripts/merge_params.py export1.json export2.json

Workflow :
1. L'établissement ajuste les paramètres dans la GUI
2. Clique "Exporter" → fichier JSON
3. Envoie par email
4. On fusionne avec merge_params.py
5. On reconstruit l'exe avec la config enrichie

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:58:47 +02:00
72b41739e0 feat: vérification ressources GPU/RAM avant exécution + évaluateur 100/100
- Nouveau module scripts/check_resources.py : état GPU/VRAM/RAM/CPU,
  require_resources() et wait_for_resources() avec polling
- Intégré dans finetune_camembert_bio.py (8 Go VRAM + 8 Go RAM)
- Intégré dans run_batch_silver_export.py (workers × 4 Go RAM)
- Évaluateur : EVA et RAI ajoutés aux termes médicaux (score 100.0/100)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:27:33 +01:00
893ecd90de feat: réduction FP + gazetteers adresses FINESS + batch parallèle + corrections multi-axes
- Token min length relevé de 2-3 → 4 chars (élimine FP EPO, IRC, SIB...)
- Stop-words enrichis : acronymes médicaux 3 lettres, termes pharma, soins infirmiers
- BDPM stop-words : ~7300 noms commerciaux + DCI/substances actives
- Gazetteers adresses FINESS : 63K patterns Aho-Corasick (position-preserving normalization)
- Filtre contextuel anatomique pour FINESS établissements
- Nouvelles regex : RE_CIVILITE_COMMA_LIST, RE_EXTRACT_NOM_UTILISE, RE_EXTRACT_PRENOM,
  RE_NUM_EXAMEN_PATIENT, RE_ADRESSE_LIEU_DIT, RE_CIVILITE_INITIALE, Dr X.NOM
- URLs complètes (RE_URL) + détection multiline
- N° venue inversé (layout-aware) + EPISODE/NDA dans _CRITICAL_PII_TYPES
- HospitalFilter désactivé pour ADRESSE/TEL/VILLE/EPISODE (identifient le patient)
- Batch silver export parallélisé (multiprocessing spawn, N workers)
- Seuil sur-masquage relevé à 8%, server.py enrichi (source regex/ner)
- Blacklist villes : COURANT, PARIS ; contexte villes étendu (UHCD, spécialités)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 09:26:56 +01:00
8588c0660b feat(phase3): CamemBERT v3 + détection villes + initiales + texte espacé + docs réglementaires
Intégration du modèle CamemBERT-bio-deid v3 (F1=0.96, Recall=0.97, 1112 docs)
et corrections qualité issues de l'audit approfondi sur 29 fichiers.

Détection des villes en texte libre :
- Automate Aho-Corasick sur 33K communes INSEE + 11.6K villes FINESS
- Stratégie contextuelle : exige un contexte géographique (à, de, vers,
  habite, urgences de, etc.) sauf pour les villes composées (Saint-Palais)
- Blacklist de ~80 communes homonymes de mots courants (charge, signes, plan...)
- Normalisation SAINT↔ST pour les variantes orthographiques
- De 18 fuites de villes à 2 cas résiduels atypiques

Masquage des initiales de prénom :
- Post-traitement regex : "Dr T. [NOM]" → "Dr [NOM] [NOM]"
- Références initiales : "Ref : JF/VA" → "Ref : [NOM]/[NOM]"

Détection texte espacé d'en-tête :
- "C E N T R E  H O S P I T A L I E R" → [ETABLISSEMENT]

Autres corrections :
- Fix regex RE_EXTRACT_MME_MR (Mr?.? → Mr.?, \s+ → [ \t]+, * → {0,4})
- Stop words médicaux : lever, coucher, services hospitaliers (viscérale, etc.)
- CamemBERT NER manager : version tracking, propriété version, log F1/Recall
- Script finetune : export ONNX automatique + mise à jour VERSION.json
- Évaluateur qualité : exclusion stop words médicaux des alertes INSEE

Documentation :
- Spécifications techniques CamemBERT-bio-deid v3
- Conformité RGPD + AI Act (caviardage PDF raster)
- AIPD (Analyse d'Impact Protection des Données)

Score qualité : 97.0/100 (Grade A), Leak score 100/100

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:16:13 +01:00
29e58188ca feat(phase2): Fine-tuning CamemBERT-bio v2 (F1=0.90) + enrichissement données
- Fine-tuning camembert-bio-base : F1=0.903, Recall=0.930 (vs 0.89/0.85)
- Data augmentation : substitution noms INSEE (219K patronymes, x3 copies)
- Hard negatives BDPM (5.7K médicaments) + QUAERO (1319 termes médicaux)
- Annotations silver enrichies par gazetteers (+612 VILLE, +5 HOPITAL)
- Export silver avec support multi-répertoires (--extra-dir)
- Gazetteers QUAERO : CHEM, DISO, PROC, ANAT depuis DrBenchmark/QUAERO
- Gazetteers INSEE : noms de famille fréquents (96K) et complets (219K)
- Batch silver 1194 PDFs (run_batch_silver_export.py) pour dataset v3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 02:06:08 +01:00
044b4dc867 feat(phase2): Détection établissements par Aho-Corasick sur 108K noms FINESS
- Nouveau script build_finess_gazetteers.py : extraction noms distinctifs, villes, numéros depuis CSV open data
- Automate Aho-Corasick (pyahocorasick) pour matching multi-pattern en ~1.7ms/page
- 108K patterns indexés (noms composés >= 8 chars, mots uniques >= 10 chars)
- Blacklist mots génériques (clinique, pharmacie, etc.) et stop words médicaux
- Normalisation position-preserving (sans accents, même longueur)
- Construction lazy de l'AC (après chargement des stop words)
- Intégration dans _mask_line_by_regex et selective_rescan
- Nouveau gazetteer villes_finess.txt (11,660 villes)
- Résultats : "Girandières" → masqué, "Côte Basque" → masqué, 0 FP sur termes médicaux courants

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 22:56:43 +01:00
2abb9afede feat(phase2): Gazetteers FINESS 102K établissements + fine-tuning CamemBERT-bio F1=89%
Gazetteers FINESS (data.gouv.fr open data):
- 102K numéros FINESS → détection par lookup exact dans _mask_admin_label + selective_rescan
- 122K noms d'établissements, 113K téléphones, 76K adresses (disponibles)
- Un nombre 9 chiffres matchant un vrai FINESS est masqué même sans label "FINESS"

Fine-tuning CamemBERT-bio (almanach/camembert-bio-base):
- Export silver annotations réécrit : alignement original↔pseudonymisé (difflib)
  → 6862 entités B- (vs 3344 avec l'ancien audit-only) sur 222K tokens
- Sliding windows (200 tokens, stride 100) pour documents longs
- WeightedNERTrainer avec class weights cappés (max 10x) + label smoothing
- Résultat: Precision=88.1%, Recall=89.8%, F1=88.9% (20 epochs, lr=1e-5)
- Modèle sauvegardé dans models/camembert-bio-deid/best (non commité)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 13:27:37 +01:00
3590099b41 feat(phase2): Multi-signal NER — BDPM gazetteers, confiance EDS, safe patterns, GLiNER
Chantier 1: Intégration BDPM (5737 médicaments officiels) dans medication whitelist
Chantier 2: Safe patterns contextuels (dosages mg/mL/cpr, formes pharma, même ligne)
Chantier 3: Scores de confiance NER réels (edsnlp 0.20 ner_confidence_score)
Chantier 4: GLiNER zero-shot (urchade/gliner_multi_pii-v1) en vote croisé
Chantier 5: Scripts export silver annotations + fine-tuning CamemBERT-bio

0 fuite, 0 régression, -18 FP supplémentaires éliminés.
Sécurité: GLiNER ne peut rejeter que si confiance NER < 0.70.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 12:01:46 +01:00