Connaissances / Notes techniques /
Concevoir un nettoyage d'assets sécurisé pour des données qu'on ne possède pas
Il existe une catégorie d'outils où les règles normales de fiabilité logicielle se déplacent. La plupart des logiciels sont corrigeables : vous pouvez relancer la requête, annuler la migration, restaurer la sauvegarde. Le coût d'un bug se mesure en temps et en effort — agaçant, récupérable.
Les outils de nettoyage pour les projets créatifs — les outils qui peuvent localiser et supprimer des fichiers — ne correspondent pas toujours à ce modèle. Les données sur lesquelles ils opèrent n'ont pas été créées par l'outil, ne sont pas stockées par l'outil, et dans bien des cas ne peuvent être recréées par personne si elles sont perdues. Cela change ce que signifie un « comportement par défaut responsable », et cela le change d'une manière qui n'est pas évidente jusqu'à ce que quelque chose tourne mal.
Le problème de propriété
Quand vous construisez un outil qui modifie ou supprime des données utilisateur, vous opérez sur le travail de quelqu'un d'autre. C'est différent d'un outil qui génère, transforme ou traite ses propres sorties.
Un compilateur qui compile mal du code produit un binaire cassé. L'utilisateur corrige la source et recompile. La source originale est intacte. Un outil de nettoyage qui supprime un fichier dont vous aviez besoin — une illustration originale, un effet sonore sous licence, un sprite de personnage qui a demandé quarante heures de travail — ne peut pas le rendre. L'outil avait tort. La perte est permanente.
Cette asymétrie entre l'auteur et l'outil, entre ce que l'outil peut vérifier et ce que l'utilisateur sait réellement, est la contrainte de conception centrale. Chaque décision sur la manière d'agir agressivement, sur ce qu'il faut automatiser, et sur où placer la friction en découle.
Optimiser pour le mauvais mode d'échec
Un cadre courant pour évaluer les outils est de demander : « à quelle fréquence a-t-il raison ? » Un taux de précision élevé rend un outil agressif dans les résultats sûr. Si 98 % des fichiers signalés sont véritablement inutiles, vous pouvez sûrement faire confiance à l'outil pour agir dessus.
Ce cadre rate quelque chose. Le taux de 2 % de faux positifs n'est pas uniformément distribué sur des fichiers qui n'ont pas d'importance. Dans un projet Ren'Py, les faux positifs les plus probables sont précisément les fichiers les plus difficiles à récupérer :
- Les assets gérés par le moteur chargés via des chemins que le scanner ne reconnaît pas.
- Les assets utilisés dans des définitions d'écrans personnalisés ou des intégrations de plugins.
- Les fichiers réservés pour une scène en cours de développement actif.
- Les fichiers sources en haute résolution qui sont techniquement « inutilisés » mais irremplaçables.
Un taux de 2 % de faux positifs sur un projet avec 500 fichiers médias représente 10 fichiers supprimés à tort. Selon lesquels ce sont, les dommages vont du trivial au significatif. La statistique de précision de l'outil ne vous dit rien d'utile sur l'endroit où vos fichiers spécifiques se situent dans cette distribution.
Les deux types d'erreur et leurs coûts
Chaque décision de nettoyage implique deux erreurs possibles :
- Faux positif (Type I) : classer un fichier nécessaire comme inutile. Le coût dépend de la récupérabilité — du trivial (réexporter depuis la source) au grave (source originale non disponible).
- Faux négatif (Type II) : classer un fichier inutile comme nécessaire, le laissant dans le projet. Le coût est de laisser du désordre derrière — espace disque, confusion, bruit dans les résultats de recherche.
Dans la plupart des contextes logiciels, ces coûts sont à peu près comparables et l'objectif est de minimiser les deux. Pour la gestion d'assets créatifs, ils ne sont pas comparables. Un faux positif dans un nettoyage destructif peut être catastrophique. Un faux négatif ne vous coûte rien que vous n'aviez déjà.
Cette asymétrie doit orienter la conception des outils vers une tolérance plus élevée aux faux négatifs — laisser davantage si nécessaire — et une tolérance très faible aux faux positifs. Le comportement par défaut devrait être prudent. Le mode agressif devrait être opt-in, pas opt-out.
Les décisions de conception qui en découlent
Une fois que vous acceptez que le coût d'un faux positif de suppression est potentiellement illimité et que le coût d'un faux négatif est limité et faible, plusieurs décisions de conception deviennent évidentes :
Ne jamais supprimer par défaut
Aucune action de nettoyage ne devrait être le résultat par défaut d'un scan. Le scan produit des résultats. Les résultats nécessitent une révision. La suppression nécessite une confirmation explicite. Ce sont trois décisions utilisateur distinctes, pas une seule.
Montrer ce dont on n'est pas sûr
Les fichiers que le scanner ne peut pas évaluer complètement ne devraient pas être silencieusement exclus des résultats, mais ils ne devraient pas non plus être présentés comme équivalents aux candidats clairement signalés. BranchPy rend l'incertitude explicitement visible — les fichiers protégés sont visibles, avec une raison, afin que les utilisateurs puissent décider en connaissance de cause s'il convient d'approfondir l'investigation.
Séparation de la classification et de la suppression
Le code qui décide quoi afficher et le code qui effectue la suppression doivent être séparés, et la couche de suppression doit valider indépendamment l'ensemble qu'elle reçoit. Cela signifie qu'un bug dans la couche d'affichage — montrant un fichier comme sélectionnable quand il ne devrait pas l'être — ne peut pas à lui seul provoquer une opération irréversible. Il existe un verrou qui ne fait pas confiance à la couche au-dessus de lui.
Préférer les opérations réversibles partout où c'est possible
La suppression définitive est le dernier recours, pas la première option. Lorsque c'est faisable, déplacer des fichiers vers un emplacement de transit avant la suppression permanente donne aux utilisateurs une fenêtre de récupération sans nécessiter une sauvegarde. C'est une voie prévue pour BranchPy — reconnaissant que même une étape de confirmation bien conçue n'est pas un substitut à une option de récupération.
Le compromis que vous acceptez
Il y a un vrai coût aux comportements par défaut conservateurs : l'efficacité. Un outil qui exige une révision manuelle de chaque candidat, qui n'agit jamais de sa propre initiative, qui rend l'incertitude visible au lieu de la résoudre, est plus lent à utiliser qu'un outil qui nettoie simplement les choses à votre place.
Pour le cas d'utilisation de BranchPy — projets Ren'Py, souvent par des développeurs solo, souvent sans pipelines robustes de récupération d'assets — ce compromis est correct. Nous optimisons pour le résultat où un utilisateur n'a jamais à dire que l'outil a détruit quelque chose dont il avait besoin.
Ce n'est pas une réponse universelle. Pour un studio de production avec un contrôle de version complet, des systèmes DAM pour les assets et un QA dédié, un outil de nettoyage agressif peut être tout à fait approprié. Le bon niveau de prudence dépend des capacités de récupération de l'utilisateur, pas seulement de la précision de l'outil.
Résumé
- Les outils de nettoyage opérant sur des données appartenant à l'utilisateur font face à une contrainte unique : ils peuvent causer des dommages irréversibles à un travail qu'ils n'ont pas créé.
- Les statistiques de précision faussent la représentation du risque quand les faux positifs sont concentrés dans des fichiers de grande valeur et difficiles à récupérer.
- L'asymétrie de coût entre les suppressions faux positifs et les manques faux négatifs justifie des comportements par défaut délibérément conservateurs.
- La séparation structurelle entre classification, affichage et suppression empêche les défaillances en un seul point de provoquer des opérations irréversibles.
- Les états intermédiaires réversibles (quarantaine, dossiers de transit) sont préférables à la suppression définitive partout où ils ajoutent une fenêtre de récupération sans fausse confiance.
- Le bon niveau de prudence évolue selon les capacités de récupération de l'utilisateur — que BranchPy suppose par défaut comme étant limitées.