PD-86 — Expression de Besoin : Détection de contenu sensible (IA locale)¶
Story : PD-86 Epic : PD-185 — B2C-MINEURS Projet : ProbatioVault-app (iOS) Date : 2026-02-24 Auteur : PO (Loic) + Claude (orchestrateur)
1. Contexte¶
ProbatioVault est un coffre-fort numérique souverain et zero-knowledge. Dans le parcours B2C — Mineurs, la plateforme permet à des jeunes victimes de cyberharcèlement de sceller des preuves (captures d'écran, photos, vidéos, documents PDF) de manière probatoire.
Ces contenus peuvent contenir : - Des images violentes - Des contenus à caractère sexuel - De la nudité explicite - Des scènes traumatiques
Il existe une tension structurante entre : - Garantir le zero-knowledge (aucun contenu analysé côté serveur) - Protéger activement les mineurs contre l'exposition répétée à des contenus sensibles
Le point d'intervention identifié par le PO est la consultation (viewer), pas l'upload. L'utilisateur ne doit être exposé au contenu qu'après un consentement explicite si celui-ci est détecté comme sensible.
2. Objectifs principaux¶
2.1 Détection locale multi-format¶
Le système doit être capable de détecter automatiquement la présence probable de contenus sensibles dans trois types de documents :
- Images (captures d'écran, photos) : analyse directe après déchiffrement en mémoire, sur une version réduite (downscalée)
- Vidéos : analyse par échantillonnage d'un sous-ensemble de frames (pas de décodage intégral)
- Documents PDF : analyse de rendus miniatures (thumbnails) de quelques pages représentatives
Les catégories de détection attendues : - Violence explicite - Nudité - Contenu sexuel - Scènes choquantes
2.2 Alerte et consentement avant affichage¶
En cas de détection de contenu sensible : - Le système affiche un écran intermédiaire (modal de consentement) avant toute visualisation du contenu - Le modal indique la nature probable du contenu détecté (ex. : "Contenu potentiellement violent") - L'utilisateur dispose de trois actions : - Afficher quand même (avec confirmation explicite pour les mineurs) - Garder masqué (continuer sans afficher) - Ne plus me prévenir pour ce document (préférence locale) - Le système peut optionnellement proposer une preview floutée
2.3 Respect absolu du scellement probatoire¶
La détection : - Ne modifie jamais le fichier original - N'altère jamais son hash - N'interfère jamais avec l'ancrage probatoire (Merkle / blockchain) - Ne crée aucune version dérivée qui remplacerait l'original - S'exécute en mémoire sur le contenu déjà déchiffré pour le viewer
2.4 Persistance minimale des résultats¶
Le système : - Cache le résultat de classification localement par identifiant de document et version du modèle (pour éviter de re-classifier à chaque ouverture) - Stocke uniquement : flag sensible (oui/non), catégories détectées, scores arrondis, version du modèle, timestamp local - Ne stocke jamais : images extraites, frames vidéo, thumbnails PDF, embeddings, texte OCR, quoi que ce soit de reconstituable
2.5 Paramétrage utilisateur¶
Le système doit permettre : - Un consentement explicite avant affichage de tout contenu flaggé - Une désactivation éventuelle de la détection par l'utilisateur (paramètre configurable dans les réglages) - Un seuil de détection configurable (le PO recommande un seuil par défaut prudent, ajustable)
3. Non-objectifs (exclusions explicites)¶
- Pas de modération : le système ne supprime, ne bloque et ne signale jamais un contenu automatiquement
- Pas de filtrage juridique : le système ne porte aucun jugement moral ou légal sur le contenu
- Pas d'analyse côté serveur : aucun contenu n'est transmis à un serveur ou API externe
- Pas d'analyse à l'upload : la détection n'intervient qu'à la consultation (viewer), pas au moment de l'import
- Pas de parental gate : pas de mécanisme de contrôle parental (hors périmètre PD-86)
- Pas de classification de texte : la détection porte sur le contenu visuel uniquement (pas d'OCR/NLP)
- Pas de stockage serveur des résultats de classification (uniquement local)
4. Contraintes¶
4.1 Zero-knowledge (contrainte architecturale absolue)¶
- Aucun contenu en clair ne doit être transmis à des serveurs
- Aucun contenu ne doit être envoyé à une API externe d'analyse
- Aucun modèle cloud ne doit recevoir les données utilisateur
- Le modèle de classification s'exécute intégralement sur le device
4.2 Performance et expérience utilisateur¶
- La détection ne doit pas bloquer excessivement l'expérience d'ouverture d'un document
- Le PO fixe un budget temps : si l'inférence dépasse un seuil raisonnable (~700 ms), un comportement de fallback doit être prévu (modal par prudence, ou affichage avec avertissement)
- Le modèle doit pouvoir être pré-chargé (warm-up au démarrage de l'app ou à l'ouverture du coffre)
- Le downscaling agressif est attendu (la détection n'a pas besoin de résolution HD)
- L'exécution doit se faire sur un thread d'arrière-plan, sans bloquer l'UI
4.3 Sécurité des données en mémoire¶
- Aucun fichier temporaire sur disque pendant l'analyse
- Pas de logs contenant des dimensions, métadonnées ou informations reconstituables
- Zeroization best-effort des buffers après traitement (pattern try/finally issu du REX PD-242)
- Contrôle des APIs système qui pourraient cacher des thumbnails automatiquement (iOS génère des previews — à désactiver ou contrôler)
4.4 Public mineur¶
- Le système ne doit pas infantiliser l'utilisateur
- Le système doit rester explicite, clair et non culpabilisant
- Le système ne doit pas faire d'interprétation juridique ou morale
- Le modal de consentement doit être compréhensible par un adolescent
4.5 Compatibilité modèle¶
- Le modèle de classification doit fonctionner hors ligne
- Le modèle doit être embarqué dans le bundle de l'application (ou téléchargeable une fois)
- Le PO envisage un modèle au format ONNX, avec possibilité de conversion vers un format natif (CoreML pour iOS) si les performances le justifient
5. Scénarios d'échec et résultats inacceptables¶
| Scénario | Conséquence | Caractère |
|---|---|---|
| Un contenu violent est affiché sans avertissement à un mineur | Traumatisme, responsabilité juridique | INACCEPTABLE |
| Le modèle modifie ou altère le fichier original | Perte de valeur probatoire | INACCEPTABLE |
| Les données sont envoyées à un serveur pour classification | Violation zero-knowledge | INACCEPTABLE |
| Des fichiers temporaires (images, frames) persistent sur le disque | Fuite de données sensibles | INACCEPTABLE |
| L'inférence bloque l'UI pendant plusieurs secondes | UX dégradée, frustration utilisateur | DÉGRADÉ (fallback acceptable) |
| Faux positifs excessifs (images anodines flaggées) | Fatigue de l'alerte, désactivation par l'utilisateur | DÉGRADÉ (seuil ajustable) |
| Faux négatifs (contenus sensibles non détectés) | Protection insuffisante | DÉGRADÉ (risque résiduel accepté) |
| Le modèle est trop volumineux pour certains devices | App trop lourde à télécharger | DÉGRADÉ (optimisation nécessaire) |
6. Tensions et conflits non résolus¶
| Tension | Description |
|---|---|
| Protection vs Liberté | Ne pas empêcher le scellement probatoire d'un contenu choquant. L'utilisateur DOIT pouvoir sceller et consulter n'importe quel contenu, même détecté comme sensible. |
| Sécurité vs Performance | L'analyse locale est potentiellement coûteuse en CPU/GPU/batterie. Le downscaling et le budget temps atténuent mais ne résolvent pas totalement. |
| Protection mineur vs Sur-censure | Les faux positifs sont inévitables. Un seuil trop bas génère du bruit ; un seuil trop haut rate des contenus. Le PO recommande de privilégier la protection (seuil prudent). |
| Zero-knowledge vs Classification | Détecter la nature d'un contenu sans jamais l'exposer au-delà du device. Pas de fuite via logs, thumbnails système, ou fichiers temporaires. |
| Cache verdict vs Sécurité | Stocker un flag "sensible" localement améliore les performances mais crée une métadonnée exploitable. Le compromis : chiffrement du cache, données minimales. |
| Modèle unique vs Performances natives | Un seul modèle ONNX (cross-platform) simplifie la maintenance mais les formats natifs (CoreML) offrent de meilleures performances. Décision reportée à la spécification. |
| Analyse au viewer vs Latence d'ouverture | Analyser à l'ouverture ajoute de la latence. Le cache et le warm-up atténuent pour les consultations ultérieures, mais la première ouverture reste impactée. |
7. Questions ouvertes¶
| # | Question | Impact |
|---|---|---|
| Q1 | Quel modèle ONNX précis sera utilisé ? Le PO demande une évaluation comparative (NudeNet, NSFW-MobileNet, Yahoo OpenNSFW, etc.) à la spécification. | Taille du bundle, précision, latence |
| Q2 | Quel format final : ONNX Runtime Mobile direct, ou conversion CoreML pour iOS ? Le PO envisage les deux approches. | Performances, complexité de maintenance |
| Q3 | Stratégie d'agrégation pour les vidéos : max(score) ou p95(score) sur les frames échantillonnées ? | Ratio faux positifs / faux négatifs sur vidéos |
| Q4 | Combien de frames échantillonner par vidéo (8 ? 16 ?) et quelle stratégie de sélection (uniforme + début) ? | Performance vs couverture |
| Q5 | Le seuil de confiance par défaut est-il unique pour toutes les catégories ou différencié (ex. nudité 0.7, violence 0.8) ? | Calibration du modèle |
| Q6 | Le cache local de verdicts doit-il être chiffré (Core Data + Keychain) ou en clair (UserDefaults) ? Le PO recommande le chiffrement mais la décision est technique. | Sécurité vs simplicité |
| Q7 | Comportement en cas de timeout d'inférence : afficher le modal par prudence ("contenu non analysé") ou afficher directement ? | UX vs protection |
| Q8 | Les thumbnails PDF sont générés comment ? Via le framework natif PDFKit ou un renderer tiers ? | Dépendance technique |
| Q9 | Le warm-up du modèle : au lancement de l'app, à l'ouverture du coffre, ou au premier document ouvert ? | Latence perçue vs ressources |
| Q10 | La désactivation de la détection par l'utilisateur est-elle totale ou par catégorie ? | Granularité du paramétrage |
Learnings injectés (stories précédentes)¶
| Source | Learning | Application PD-86 |
|---|---|---|
| PD-248 | Plan RESERVE car stratégie de robustesse non documentée | Documenter explicitement les cas d'erreur du modèle (images corrompues, formats non supportés, modèle absent) |
| PD-242 | Pattern try/finally obligatoire pour zeroization de clés sensibles | Appliquer aux buffers d'image en mémoire après classification |
| PD-105 | Sécuriser avec whitelist, pas blacklist | Appliquer aux catégories de contenu : lister les catégories détectées (whitelist) plutôt que les catégories ignorées |