# Memoire projet

Derniere mise a jour : 2026-04-22

## Objet

But du projet : anonymiser/pseudonymiser des documents medicaux de facon fiable, diffable, validable par des humains, avec une contrainte forte de conformite et de non-fuite.

Ce fichier sert de point de reprise rapide pour ne pas perdre le fil entre deux sessions.

## Etat courant

- La source de verite des dictionnaires par defaut est `config/dictionnaires.default.yml`.
- La surcharge runtime/site est `config/dictionnaires.yml`.
- Les dictionnaires hardcodes ont ete externalises vers `data/`.
- Les regles d'administration ont un contrat dedie :
  - `config/admin_rules.default.yml`
  - `config/admin_rules.yml`
  - `schemas/admin_rules.schema.json`
  - `admin_rules.py`
- Les regles admin sont branchees dans le moteur ONNX.
- Le core legacy n'est pas encore aligne sur ce branchement admin.
- La GUI conserve maintenant le chemin relatif des cas sous `anonymise/` au lieu d'ecraser les sorties homonymes.
- La GUI ignore maintenant le sous-dossier `anonymise/` lors du scan recursif des entrees.
- L'onglet Parametres de la GUI charge maintenant les listes effectives `default + overlay`, donc les phrases/termes par defaut sont visibles meme si `config/dictionnaires.yml` est vide.
- L'onglet Parametres affiche aussi un resume chiffré des listes visibles et precise que le moteur applique d'autres regles automatiques non affichees dans ces champs.
- La GUI expose maintenant un mode `masques PDF reutilisables` pour les documents formates :
  - ouverture d'un editeur de caviardage manuel depuis l'onglet Parametres
  - stockage persistant des templates dans `config/mask_templates/`
  - ouverture automatique du PDF courant quand l'utilisateur a selectionne un fichier PDF
  - selection d'un template dans la GUI pour l'appliquer a tous les PDF du lot avant anonymisation
- La GUI expose maintenant aussi des `profils metier` :
  - definitions chargees depuis `config/profiles.default.yml` + `config/profiles.yml`
  - selection d'un profil dans l'onglet Parametres
  - surcharge de configuration appliquee au moteur pour le lot courant
  - options de poste utilisateur prises en compte comme `masque manuel requis` et `VLM desactive`
- Le moteur anonymise maintenant correctement deux layouts reels supplementaires :
  - numero de venue BACTERIO rejete juste avant `IPP`
  - artefacts de noms de fichiers scannes `EXT2-...-1234567890.TIF`

## Validation deja en place

- Suite rapide : `tests/synthetic_regression/`
- Corpus complet de revue : `tests/synthetic_review/`
- Runner de revue : `tools/run_synthetic_review_corpus.py`
- Protocole humain : `docs/protocole-validation-humaine.md`
- Fiche de revue : `docs/fiche-validation-humaine-modele.md`

Tests ajoutes/maintenus :

- `tests/unit/test_config_externalization.py`
- `tests/unit/test_header_pii_detection.py`
- `tests/unit/test_synthetic_regression.py`
- `tests/unit/test_admin_rules_validator.py`
- `tests/unit/test_admin_rules_integration.py`
- `tests/unit/test_gui_batch_paths.py`

## Commits repere

- `500ebc2` Externalize dictionaries and add anonymization review corpus
- `b58d79f` Add project framing for anonymization
- `0fc8665` Add human review protocol and admin rules contract
- `df5dabf` Wire admin rules into ONNX anonymizer

## Dernier constat important

La campagne lancee depuis la GUI sur le dossier global `tests/synthetic_regression/cases` n'est pas exploitable comme validation complete.

Cause racine :

- la GUI parcourt recursivement tous les fichiers supportes du dossier choisi
- la GUI ecrit toutes les sorties dans un seul dossier `anonymise/`
- les sorties sont nommees avec le seul `stem` du fichier source
- comme chaque cas contient `input.txt`, `test.txt` et `expected.txt`, les sorties s'ecrasent entre elles

Rapport detaille :

- `docs/rapport-analyse-campagne-gui-2026-04-21.md`

Conclusion :

- seul le cas `010_spaced_establishment_header` restait encore verifiable
- ce cas etait conforme
- la campagne globale est non concluante pour les autres cas

## Correctif applique ensuite

Le probleme de nommage GUI identifie ci-dessus a ete corrige dans `Pseudonymisation_Gui_V5.py`.

Effets du correctif :

- les sorties de campagne conservent desormais le sous-dossier relatif de chaque cas
- le dossier `anonymise/` est exclu des entrees candidates, pour eviter les retraitements accidentels
- le controle de fuite GUI relit desormais les `.pseudonymise.txt` de facon recursive

Exemple attendu :

- `anonymise/001_patient_header_and_birth/test.pseudonymise.txt`
- `anonymise/002_contact_bundle/test.pseudonymise.txt`

## Echantillon reel CHUXX du 2026-04-22

Lot teste :

- dossier source : `/home/dom/Téléchargements/II-1 Ctrl_T2A_2025_CHUXX_DocJustificatifs`
- echantillon aleatoire reproductible de 30 documents
- manifeste : `anonymise/_sample_manifest_2026-04-22_seed20260422.json`

Resultat de traitement :

- 27 documents anonymises avec succes
- 3 echecs dus a des PDF proteges par mot de passe :
  - `149_23089771/ANAPATH 23089771.pdf`
  - `26_23127395/ANAPATH 23127395.pdf`
  - `29_23137897/ANAPATH 23137897.pdf`

Validation apres correctifs moteur :

- 2 fuites probables observees au premier passage ont ete corrigees :
  - `228_23176885/BACTERIO 23176885.pdf`
  - `84_23215994/trackare-16014215-23215994_16014215_23215994.pdf`
- controle automatique final : 22 documents sans fuite detectee sur 27
- les 5 alertes restantes sont des faux positifs connus du `LeakScanner`
  - initiales d'une lettre dans l'audit (`A`, `F`, `S`)
  - code produit `16371071` dans une ligne CLARISCAN
  - ratio medical `1/10000`

Rapports produits :

- `anonymise/_sample_run_report_2026-04-22_seed20260422.json`
- `anonymise/_sample_validation_report_2026-04-22_seed20260422.json`
- `anonymise/_sample_validation_triage_2026-04-22_seed20260422.json`

## Prochaine action recommandee

Relancer soit :

- une nouvelle vague aleatoire de 30 documents reels CHUXX
- soit la campagne de validation sur `tests/synthetic_regression/cases`

Objectif :

- separer les vrais ecarts moteur des faux positifs du validateur
- prioriser ensuite une amelioration du `LeakScanner` pour ignorer les hits NOM mono-lettre et certains numeriques medicaux non patients

Option recommandee :

- verifier d'abord que la GUI ne traite plus `anonymise/` comme entree
- lancer une passe complete sur le corpus
- confirmer visuellement que chaque cas produit sa sortie dans son propre sous-dossier

Amelioration utile ensuite :

- ajouter un mode GUI "campagne de tests" qui ne traite que `test.txt`
- generer automatiquement un rapport de comparaison contre les `expected.txt`

## Fichiers a relire en premier pour reprendre

- `docs/cadrage-projet-anonymisation.md`
- `docs/spec-regles-administration.md`
- `docs/protocole-validation-humaine.md`
- `docs/rapport-analyse-campagne-gui-2026-04-21.md`
- `gui_batch_paths.py`
- `anonymizer_core_refactored_onnx.py`
- `Pseudonymisation_Gui_V5.py`

## Etat du worktree a ne pas confondre avec le chantier courant

Il existe des changements hors perimetre qu'il ne faut pas ecraser par erreur :

- suppressions sous `ano/pdf_natif/pseudonymise/`
- gros volume non tracke sous `data/silver_annotations/`
- sorties generees sous `tests/synthetic_review/actual/`
- sorties GUI sous `tests/synthetic_regression/cases/anonymise/`

## Regle de reprise

Avant toute nouvelle passe de validation humaine sur corpus :

1. verifier le mode de sortie de la GUI
2. eviter de traiter le dossier global tant que le nommage de sortie n'est pas corrige
3. preferer un cas a la fois si la GUI n'a pas encore ete corrigee

## Derniere avancee

Les profils metier ne sont plus seulement lus depuis YAML :

- la GUI permet maintenant de creer un nouveau profil
- la GUI permet d'enregistrer les reglages courants dans le profil selectionne
- les profils utilisateur sont ecrits dans `config/profiles.yml`
- un profil peut memoriser :
  - les listes visibles de preservation / masquage / stop-words
  - le caractere obligatoire du masque manuel
  - la desactivation du VLM
  - le modele de masque PDF prefere

Effet important :

- la selection d'un profil recharge maintenant ses reglages visibles dans l'onglet Parametres
- le lancement de traitement utilise les reglages courants de l'ecran via une config temporaire de lot, sans exiger un `Sauvegarder` prealable dans `dictionnaires.yml`

Ergonomie GUI :

- l'onglet `Parametres` a ete simplifie pour un usage bureautique
- la navigation est maintenant organisee en trois onglets stables :
  - `Anonymisation`
  - `Parametres`
  - `Profils`
- les listes manuelles sont revenues directement dans `Parametres`
- la creation / edition / suppression / profil par defaut sont gerees directement dans l'onglet `Profils`
- on evite ainsi les enchainements de popups pour le flux normal
- l'onglet `Profils` expose maintenant explicitement le `masque PDF memorise par ce profil`
- le sens de `masque manuel obligatoire` est documente dans l'UI :
  - cela n'impose pas un masque precis
  - cela bloque seulement le lancement si aucun masque PDF n'est selectionne

Packaging Windows :

- le build Windows a maintenant un point d'entree "un clic" : `build_windows_oneclick.bat`
- ce lanceur appelle `scripts/build_windows_oneclick.ps1`
- le packaging utilise `PyInstaller` via `anonymisation_onefile.spec`
- le `.spec` n'est plus fige sur `C:\Users\dom\ai\anonymisation` ; il resolve maintenant le projet de facon portable
- les repertoires de configuration, donnees, detecteurs, assets et modele ONNX sont embarques dans l'executable
- sur la machine Windows de build, la sortie attendue est :
  - `dist\Anonymisation.exe`
  - `release\Anonymisation-Windows\`
  - `release\Anonymisation-Windows.zip`
  - `release\Anonymisation.exe.sha256.txt`
- objectif produit :
  - les utilisateurs finaux n'ont pas besoin d'installer Python
  - le build doit en revanche etre realise depuis un poste Windows
- risque Windows identifie :
  - un executable PyInstaller non signe peut declencher SmartScreen / Defender
  - meme signe, un nouveau hash peut encore afficher un avertissement de reputation selon les politiques Windows
  - `scripts/build_windows_oneclick.ps1` accepte maintenant une signature Authenticode via `-Sign`
  - un fichier local non versionne `build_signing.local.ps1` peut activer la signature automatiquement pour conserver le build en un clic
  - le modele de configuration est `build_signing.example.ps1`

Build Windows realise le 2026-04-23 via SSH sur `dom@192.168.1.11` :

- poste : `DESKTOP-58D5CAC`
- chemin projet Windows : `C:\Users\dom\ai\anonymisation`
- executable cree : `C:\Users\dom\ai\anonymisation\dist\Anonymisation.exe`
- archive creee : `C:\Users\dom\ai\anonymisation\release\Anonymisation-Windows.zip`
- hash : `C:\Users\dom\ai\anonymisation\release\Anonymisation.exe.sha256.txt`
- SHA256 final : `8F3E3786D669F44824D24BF14AC06EF22CE19A8E900056DAB031891791871841`
- taille exe : environ 697 MB
- contenu OCR : `python-doctr`, `torchvision`, `opencv-python`, `scipy` embarques dans l'environnement de build
- signature : non signee, car aucun certificat n'est configure
- smoke test : lancement de l'exe OK ; processus encore vivant apres 45 secondes, puis arret volontaire

Correctif build Windows du 2026-04-23 :

- probleme constate au lancement utilisateur : `No module named admin_rules`
- cause : `admin_rules.py` n'avait pas ete synchronise sur le poste Windows avant le build precedent
- correction : transfert de `admin_rules.py` sur `C:\Users\dom\ai\anonymisation`
- durcissement : `scripts/build_windows_oneclick.ps1` verifie maintenant la presence des modules source critiques avant PyInstaller
- nouveau build cree : `C:\Users\dom\ai\anonymisation\dist\Anonymisation.exe`
- nouveau SHA256 : `0EB97B1E2859D0BCD6E45DC420CFDC929C3B79B6B0AF123CF59F2230187F5712`
- smoke test : lancement de l'exe OK ; processus encore vivant apres 60 secondes, puis arret volontaire

Demarrage produit / installateur Windows du 2026-04-23 :

- le lanceur conserve le splash visuel `aivanonym` existant
- apres le splash natif PyInstaller, une fenetre de demarrage applicative reprend le meme visuel et affiche :
  - etapes numerotees de chargement
  - barre de progression
  - journal court des modules/dictionnaires charges
- la fenetre de configuration initiale affiche aussi le visuel produit et un journal des chargements de modeles
- les sorties `stdout/stderr` de type `tqdm` pendant le chargement EDS-Pseudo / GLiNER sont redirigees vers ce journal pour montrer les poids/modules en cours
- un script Inno Setup a ete ajoute : `installer/Anonymisation.iss`
- le build Windows peut maintenant produire un vrai installateur : `release\Anonymisation-Setup.exe`
- l'installateur propose :
  - choix du dossier d'installation
  - installation utilisateur sans droit administrateur par defaut
  - raccourci menu Demarrer
  - option icone bureau
  - desinstallation Windows standard
- `scripts/build_windows_oneclick.ps1` genere l'installateur si Inno Setup 6 est present ; sinon il conserve EXE/ZIP et affiche un avertissement
- verification locale Linux : `python3 -m py_compile launcher.py Pseudonymisation_Gui_V5.py camembert_ner_manager.py eds_pseudo_manager.py gliner_manager.py`
- smoke test local du nouveau splash : OK
- build Windows non relance a ce stade : authentification SSH refusee lors de la tentative de reconnexion au poste Windows

Build Windows installateur realise le 2026-04-23 via SSH sur `dom@192.168.1.11` :

- Inno Setup 6.7.1 installe en mode utilisateur sur le poste Windows via `scripts/install_inno_setup_build_dep.ps1`
- chemin Inno : `C:\Users\dom\AppData\Local\Programs\Inno Setup 6\ISCC.exe`
- build relance avec `scripts\build_windows_oneclick.ps1 -SkipRequirements`
- executable cree : `C:\Users\dom\ai\anonymisation\dist\Anonymisation.exe`
- archive creee : `C:\Users\dom\ai\anonymisation\release\Anonymisation-Windows.zip`
- installateur cree : `C:\Users\dom\ai\anonymisation\release\Anonymisation-Setup.exe`
- taille executable : `730 483 452` octets, environ 696.6 MB
- taille ZIP : `728 300 929` octets
- taille installateur : `729 517 505` octets, environ 695.7 MB
- SHA256 executable : `520EE614CD9B56EB7C748AB5BCCDF0DD4DAAD0726EF0EAB0EFE89177A84E5882`
- SHA256 installateur : `A22B5D1A3AE10203DEEA7FB053C0184695A88084294603CF1EA643F123597FC1`
- signature : non signee, car aucun certificat Authenticode n'est configure
- smoke test Windows : lancement de `dist\Anonymisation.exe` OK ; deux processus `Anonymisation` repondants apres 60 secondes, puis arret volontaire
