Première version diffusable. Anonymise un texte entièrement en local, avec une
application de bureau, une ligne de commande et un harnais d'évaluation.

### Le moteur

- Pipeline en sept étapes : dictionnaire, détecteurs déterministes, détecteur
  contextuel, fusion des spans, allowlist, substitution, vérification.
- Détecteurs déterministes : motifs réseau et identifiants, 23 règles de
  secrets pilotées par un fichier TOML, affectations clé/valeur et chaînes de
  connexion, entropie de Shannon, dictionnaire utilisateur.
- Le détecteur contextuel travaille sur le texte **déjà pré-masqué**. Quand un
  modèle est appelé, les secrets, adresses et identifiants ont déjà disparu.
- Substituts pris dans les plages réservées à la documentation — RFC 5737,
  3849, 2606, 7042 et les tranches de fiction de l'ARCEP — jamais réattribués,
  et reconnus par l'allowlist pour que repasser un texte déjà anonymisé ne le
  dégrade pas.
- Cohérence préservée : deux adresses d'un même sous-réseau restent dans le
  même sous-réseau substitut, les sous-domaines survivent, la structure d'une
  URL ou d'une chaîne de connexion aussi.

### L'application

- Deux panneaux, un axe central portant l'action, un badge de statut permanent.
- Surlignage par famille d'entités, infobulle donnant le type, le substitut, le
  détecteur et la confiance, avec la valeur d'origine floutée jusqu'à demande.
- Exclusion d'une fausse détection, marquage manuel d'une sélection,
  dictionnaire et allowlist éditables, rapport au format figé.
- Onglet Restaurer, raccourci global, import et export des réglages.
- Effacement temporisé du presse-papier, qui ne vide que si le contenu est
  toujours celui que l'application y a mis.
- Thème clair et sombre, suivant le système.

### Détecteurs contextuels

- **Ollama** : découverte des modèles installés, sortie contrainte par schéma
  JSON, découpage avec chevauchement, tentatives, et vérification que chaque
  valeur proposée existe littéralement dans le texte.
- **GLiNER2** via ONNX Runtime, sous *feature* de compilation.
- Chaîne de repli `ollama → gliner → déterministe`, jamais silencieuse.
- Modèle par défaut `qwen2.5:14b`, retenu par mesure et non par hypothèse :
  90 % de rappel contextuel sur le corpus, seul au-dessus de l'objectif de
  85 %, contre 67 % pour `qwen2.5:3b` et 33 % pour `llama3.2:3b`. Voir
  [docs/BENCHMARK.md](docs/BENCHMARK.md).

### Confidentialité

- Aucune sortie réseau hors boucle locale. L'URL du détecteur est validée
  **et son adresse épinglée** : un `localhost` détourné par `/etc/hosts` est
  refusé, et le client se connecte à l'IP vérifiée plutôt qu'à un nom.
- Le mapping de session ne quitte pas la mémoire, est purgé par `zeroize`, et
  n'apparaît ni dans les journaux, ni dans le rapport, ni dans le contrat de
  sortie. Les valeurs d'origine passent par une commande dédiée, entité par
  entité, sur action explicite.
- Aucune télémétrie, aucun rapport de crash distant, aucune mise à jour
  automatique, aucun compte. Le texte analysé n'est jamais écrit sur disque.
- La suite de tests est rejouée dans un environnement privé de réseau, après
  vérification que cette isolation coupe réellement le réseau.

### Mesuré

- 285 tests. Rappel et précision à 100 % sur les types déterministes du corpus,
  neuf cas, pièges compris.
- Détection déterministe à 9 ms pour 50 000 caractères, pour un budget de 50 ms.

### Limites connues

- **Les binaires ne sont pas signés.** Windows affichera « Windows a protégé
  votre PC » au premier lancement, macOS demandera une confirmation au premier
  démarrage.
- **L'inférence GLiNER n'a jamais été exécutée.** Le détecteur compile et ses
  tests unitaires passent, mais aucun modèle ONNX n'était disponible sur la
  machine de développement. Le backend Ollama, lui, a été vérifié en conditions
  réelles.
- **Le binaire Windows est compilé de façon croisée** depuis macOS, voie que
  Tauri qualifie de dernier recours. L'installateur `.msi` n'est pas produit :
  il exige une machine Windows.
- L'annulation d'une analyse en cours, prévue au cahier des charges, n'est pas
  exposée par l'interface.
- Un statut « Complet » signifie que le traitement est allé au bout, pas que
  plus rien de sensible ne subsiste. Sans détecteur contextuel, le rapport
  l'annonce explicitement.

[1.0.0]: https://github.com/jrechet/promptscrub/releases/tag/v1.0.0
