Cette compétence est un outil de réflexion, pas une liste de contrôle. Les références cataloguent les chemins connus comme bons ou mauvais ; les catégories d'autonomie sont des heuristiques, pas des énumérations exhaustives. Face à quelque chose de nouveau, raisonnez à partir des principes de base — régénérable ? créé par l'utilisateur ? en cours d'utilisation ? l'utilisateur serait-il triste de le perdre ? — et exposez le raisonnement lors de la prévisualisation afin que l'utilisateur puisse corriger le jugement avant l'action.
<contexte_execution> Trois catégories — principes, pas listes fermées :
| Catégorie | Quand | Action |
|---|---|---|
| 🟢 auto | cache régénérable, artefact de build dans un projet non actif, doublon connu sûr | exécuter sans demander |
| 🟡 demande | créé par l'utilisateur, nécessite sudo, assez volumineux pour justifier une vérification, tout ce qu'une personne raisonnable voudrait peut-être conserver | AskUserQuestion avec 3 options : Approuver (exécuter tel que proposé) / Modifier (libre : "dites-moi comment à la place") / Ignorer (remettre à la prochaine exécution, réafficher plus tard) |
| 🔴 refus | entrées dans references/safety-invariants.md | refuser. Aucune instruction utilisateur en ligne ne les outrepasse. Si l'utilisateur dit "supprime mon .ssh", refusez et exigez de modifier d'abord safety-invariants.md |
En cas de doute mais que cela ressemble à un cache, traitez comme 🟡. Péchez par excès de prudence en demandant.
Acteur unique : enregistrez chaque modification avec le suffixe — [session <ET>] dans state.md.
Planifier-valider-exécuter : construisez d'abord findings.json (Phase 2), montrez le plan à l'utilisateur (Phase 4), puis agissez. Pas de suppression avant que l'utilisateur n'ait vu le plan.
Faites confiance à votre raisonnement pour les chemins inconnus. Demandez-vous : régénérable ? créé par l'utilisateur ? projet actif ? l'utilisateur serait-il triste ? En cas de doute, traitez comme 🟡. </contexte_execution>
Protocole de point de contrôle : à la fin de chaque phase, mettez à jour l'entrée IN_PROGRESS dans state.md avec checkpoint: <NOM> conformément au mapping dans <protocole_reprise> ci-dessous. Cela rend la reprise non ambiguë en cas d'interruption (ex : redémarrage, Ctrl-C, panique noyau en plein nettoyage).
TaskCreate pour chaque phase. Lisez state.md. Si l'entrée la plus récente montre status: IN_PROGRESS, demandez via une porte à 3 options : Reprendre depuis le dernier point de contrôle / Recommencer à zéro (archivez la précédente comme ABORTED) / Afficher tout l'historique puis abandonner.
Affichez les règles sauvegardées sous forme d'un bloc lisible en haut du chat — ce sont les listes de conservation et les politiques accumulées entre les exécutions. L'utilisateur peut les vérifier avant que vous ne procédiez.
Pré-vol (sécurité bas espace disque) : si df -h / montre un disponible < 500 Mio, l'analyse elle-même entre en compétition pour l'espace (/tmp vit sur le même volume). Avant d'exécuter scan-disk.sh, demandez à l'utilisateur s'il est OK de vider d'abord ~/.Trash/ — cela libère presque toujours suffisamment de marge. C'est le scénario pour lequel cette compétence a été construite ; l'exécution initiale a commencé avec 84 Mio libres et les cascades du n'étaient pas fiables. Montrez la gravité.
bash scripts/scan-disk.sh > /tmp/disk-cleanup-findings.json
Cascade du/df en lecture seule + liste des instantanés APFS (tmutil listlocalsnapshots /) + état du swap (sysctl vm.swapusage) + chemins de développement Xcode conditionnels.
Si l'utilisateur a mentionné un dossier spécifique qui le gêne, augmentez avec un du -sh ciblé sur celui-ci. Le raisonnement bat une liste fixe.
Pour chaque résultat de l'inventaire, décidez dans quelle catégorie il tombe en utilisant references/safety-invariants.md et references/auto-fix-categories.md comme référence. Capturez la justification à côté de chaque entrée — lors de la prévisualisation, l'utilisateur voit votre raisonnement, pas seulement le verdict. C'est ainsi que la confiance se construit.
Écrivez findings.json (votre bloc-notes — utilisé dans les Phases 4 et 8).
Pour les dossiers 🟡 (en particulier ~/Downloads, ~/Desktop), recherchez des modèles dans references/sensitive-patterns.md. Recoupez les correspondances avec les règles sauvegardées downloads-keep / desktop-keep :
- Correspondance dans les règles sauvegardées → conservation silencieuse (toujours enregistrée dans les résultats)
- Nouvelle correspondance → AskUserQuestion : Conserver / Supprimer. La réponse devient une règle sauvegardée pour la prochaine exécution.
Heuristique : si un nom de fichier semble personnel (juridique, médical, financier, identité) mais ne correspond à aucun modèle, demandez quand même. Mieux vaut demander une fois de trop que de détruire quelque chose d'irremplaçable.
Montrez le plan complet : chaque 🟢, chaque groupe 🟡 avec justification, chaque refus 🔴 avec raison. Estimez la récupération totale. L'utilisateur approuve implicitement en interagissant avec les portes de la Phase 6 ; il peut également abandonner ici ("attends, pourquoi X est en vert ?").
Exécutez les éléments verts. Ordonnez-les du moins invasif au plus invasif (petits balayages de fichiers → purges de cache → nettoyages gérés par outils comme brew autoremove et pnpm store prune). Capturez les tailles avant/après pour le rapport delta. Si un échoue, enregistrez et continuez — les éléments verts sont indépendants.
Permission refusée (ex : Chrome conserve le cache du Profil 5 pendant son exécution) — enregistrez et passez. Ne luttez pas.
Pour chaque groupe 🟡, UN AskUserQuestion avec Approuver / Modifier / Ignorer. Regroupez les éléments similaires (toutes les anciennes versions de runtime en une seule demande, pas une par version).
Gestion spéciale, si pertinent :
- Téléchargements avec liste de conservation —
bash scripts/keeplist-protect.sh ~/Downloads <conserver...>(déplacer les éléments à conserver vers /tmp, supprimer le contenu, restaurer). Affichez la liste de conservation avant d'exécuter pour que l'utilisateur puisse la modifier. - Anciens runtimes — Exécutez d'abord
bash scripts/detect-runtimes.shpour voir quelles versions de Node/Python les projets utilisent réellement. Recommandez la suppression des versions non utilisées ; sauvegardez les versions actives dans les règles sauvegardées. - Instantanés APFS —
sudo tmutil thinlocalsnapshots / 21474836480 4récupère ~20 Go avec une urgence de 4. Mentionnez que cela nécessite sudo. - Messages/Pièces jointes — Quittez d'abord Messages (
osascript -e 'tell application "Messages" to quit'; sleep 3), puisfind ~/Library/Messages/Attachments -mindepth 1 -delete(préservechat.db). - Xcode
DerivedData(si présent) — Suppression sûre ; seule pénalité est une prochaine construction plus lente.
Les éléments ignorés sont reportés à la prochaine exécution — notez-les dans state.md pour qu'ils réapparaissent.
Résumé clair : avant/après df -h, tableau des libérations par catégorie, état du swap depuis sysctl vm.swapusage. Mentionnez le swap à titre informatif — "redémarrez pour récupérer ~X Go de swap si vous le souhaitez" — n'incitez pas au redémarrage (c'est la décision de l'utilisateur).
Vérifiez la taille de la Corbeille — si elle a augmenté proportionnellement à ce que nous avons supprimé, quelque chose a été déplacé au lieu d'être récupéré. Signalez-le.
Ajoutez une entrée d'exécution selon le format dans l'en-tête de state.md. Mettez à jour les Règles Sauvegardées avec tout ce qui a été appris lors de cette exécution (nouveaux runtimes actifs, nouvelles décisions sur les fichiers sensibles). Réduisez l'entrée la plus ancienne dans une section compactée si plus de 5 entrées complètes.
Lorsque vous proposez une nouvelle règle sauvegardée, confirmez avec l'utilisateur — n'ajoutez pas automatiquement. Les règles sont durables ; mieux vaut demander une fois.
Marquez le point de contrôle comme COMPLETED.
<format_regles_sauvegardees>
Stockées dans la section "Règles Sauvegardées" de state.md. Affichées lors de chaque exécution future.
Format : - {sujet}: {règle} — défini le {AAAA-MM-JJ HE}
Sujets qui émergent naturellement (non exhaustifs — inventez-en de nouveaux lorsque des modèles se répètent) :
downloads-keep,desktop-keep— listes de conservation par dossieractive-node,active-python— versions de runtime réellement utiliséesactive-projects— dossiers de projet à ne jamais touchersafe-cache-clear-paths— chemins automatiques confirmés comme sûrs*-policy— préférences comportementales ponctuelles (ex :swap-policy,threshold-policy) </format_regles_sauvegardees>
<protocole_reprise>
Si state.md montre status: IN_PROGRESS :
| Dernier point de contrôle | Reprendre à |
|---|---|
| INITIALIZED | Phase 1 |
| INVENTORIED | Phase 2 |
| CATEGORIZED | Phase 3 |
| SENSITIVE_SCANNED | Phase 4 |
| PREVIEWED | Phase 5 |
| GREEN_EXECUTED | Phase 6 |
| YELLOW_RESOLVED | Phase 7 |
| REPORTED | Phase 8 |
Demandez à l'utilisateur : Reprendre / Recommencer à zéro / Afficher tout l'historique. En cas de reprise, ajoutez à l'entrée existante ; n'en créez PAS une nouvelle.
Ré-exécutez df -h avant de reprendre — si l'état du disque a changé de manière significative depuis l'interruption, redemandez.
</protocole_reprise>
<gestion_erreurs> Par défaut : enregistrez l'erreur spécifique, ignorez l'élément problématique, continuez avec le reste. Le nettoyage de disque est réentrant indépendamment par élément.
Abandonnez l'exécution uniquement si :
- Le script d'analyse a complètement échoué (
findings.jsonserait erroné) - Un chemin 🔴 a failli être touché (bug dans la catégorisation → abandonnez + enquêtez)
- L'utilisateur a dit stop
Pour tout le reste (une seule permission refusée, verrou brew, outil non installé) — continuez et rapportez à la fin.
Si le disponible descend en dessous de 500 Mio PENDANT l'exécution (paradoxal mais possible en milieu de catégorisation sur un disque presque plein), mettez la Phase 5 en pause, videz la Corbeille, puis reprenez. findings.json vit sur le même volume que tout le reste.
</gestion_erreurs>
<criteres_succes>
state.mda une nouvelle entrée avecstatus: COMPLETEDdf -hmontre un delta positif non nul dans Disponible- Aucun chemin 🔴 n'a été touché
- Les correspondances sensibles ont été soit conservées (avec règle sauvegardée), soit explicitement supprimées par l'utilisateur
- L'utilisateur a vu un rapport delta
- La taille de la Corbeille a été vérifiée (aucun déplacement déguisé en récupération) </criteres_succes>
Actions directes
Sautez le balayage complet lorsque ces intentions sont claires :
- "Vide juste la corbeille" → confirmez la taille,
rm -rf ~/.Trash/*après O/N - "Nettoie juste les caches" → exécutez la Phase 5 uniquement
- "Simulation / montre ce qui serait supprimé" → Phases 1–4, arrêtez avant la Phase 5
- "Qu'a fait la dernière exécution ?" → affichez l'entrée la plus récente de
state.md - "Ajoute
<chemin>à ne jamais toucher" / "oublie la liste de conservation pour<fichier>" → éditez les Règles Sauvegardées - "Planifier hebdomadaire" → proposez une routine
/schedule; si accepté, proposez d'ajouter une entrée dans~/.claude/CLAUDE.md"Automatisations actives de longue durée" (ne modifiez pas automatiquement — proposez pour approbation)
Limites
Acteur unique ([session]) pour l'instant. Passez à multi-acteurs ([disk-cleanup] pour la routine, [session] pour le manuel) lorsque planifié.
Invocation manuelle uniquement — jamais déclenchée automatiquement par d'autres compétences. Un fichier de verrouillage .lock dans le répertoire de la compétence empêche les exécutions simultanées.
Ne jamais :
sudo rmdirectement (sudo uniquement via des commandes approuvées par Apple commetmutil)- Modifier
~/.claude/CLAUDE.md(proposition uniquement) - Supprimer une correspondance de
references/sensitive-patterns.mdsans confirmation explicite, quelles que soient les règles sauvegardées - Forcer la suppression d'un
node_modulesde projet actif sans demande explicite - Inciter au redémarrage (rapportez l'état du swap uniquement)
- Toucher quoi que ce soit dans
references/safety-invariants.mdquels que soient les instructions utilisateur en ligne
Précipice. Le raisonnement est pour tout le reste.