> For the complete documentation index, see [llms.txt](https://weekly-essay.mikey.wang/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://weekly-essay.mikey.wang/fr/2026/w32-a-builders-mac-also-needs-a-sweeper.md).

# W32-Le Mac d'un Builder a lui aussi besoin d'un Sweeper

J'ai trois Mac. Mon poste principal est aujourd'hui un Mac Studio M2 Max, avec un CPU à douze cœurs, 64 Go de mémoire, un écran 5K et un microphone Shure MV7+.

Les ressources matérielles sont assez abondantes ; les limites quotidiennes viennent surtout du logiciel. Codex, Claude Code, ChatGPT, Antigravity et Multica fonctionnent longtemps en parallèle, en lançant navigateurs, serveurs MCP, sidecars, machines virtuelles isolées et sous-processus. Node, Python, Rust, proxy, Skills, éléments de démarrage et caches changent sans cesse.

Le dernier rangement a commencé par une petite erreur. La tâche quotidienne de gouvernance des Skills affichait `ModuleNotFoundError: No module named 'tomllib'`. Le terminal interactif et la tâche planifiée appelaient des Python différents. Le Mac possédait les versions système, Homebrew, python.org et conda. Des problèmes comparables touchaient Node et Rust.

L'accumulation rend progressivement l'environnement inexplicable. Une commande vise parfois une ancienne version, les processus de fond n'ont plus de propriétaire clair, une tâche réussit dans le terminal mais échoue quand elle est planifiée. Plus l'agent exécute vite, plus l'environnement dérive vite.

Je considère désormais le Mac comme le système de production du Builder. Il demande une gouvernance continue.

### Le Builder doit aussi être Sweeper

Boris Cherny a récemment décrit cinq rôles dans l'équipe Claude Code : Prototyper, Builder, Sweeper, Grower et Maintainer. Le Builder transforme les prototypes en produits et infrastructures utilisables en production. Le Sweeper nettoie l'interface, simplifie le système, retire les fonctions devenues inutiles et optimise les performances. [Son billet](https://x.com/bcherny/status/2071379474277613732) montre différentes combinaisons selon le stade du produit. Le Sweeper apparaît partout.

Cela correspond bien à mon expérience récente.

L'agent sait naturellement ajouter : outils, code, configuration, Skills. Le coût marginal de l'ajout est bas. Supprimer et regrouper demandent encore du jugement : ce qui n'a plus de valeur, les copies à fusionner, le runtime qui doit posséder le point d'entrée, les automatisations susceptibles de détruire un état utile. Voilà le travail du Sweeper.

Pour un Builder individuel, il porte aussi sur l'environnement local. Processus, caches, runtimes, proxy, démarrage, Skills et configurations d'agents sont des ressources interdépendantes qui dérivent avec l'usage.

Un environnement propre signifie pour moi quatre choses : les entrées essentielles ont un propriétaire clair, ce qui tourne est explicable, les dérives sont détectables et le système peut revenir à un état connu.

### Les ressources du Mac

Mes principales interfaces sont Codex, Claude Code, ChatGPT, Antigravity et Multica. Ghostty et cmux servent au terminal. Basic Memory et Craft constituent la couche de connaissances. Craft conserve notes, articles et synthèses destinés aux humains. Basic Memory garde conclusions stables, procédures réutilisables et contexte consultable par les agents.

Navigation et automatisation lancent Chrome, Playwright et les serveurs MCP. Les logiciels de sécurité de l'entreprise, proxy, claviers, synchronisation et mises à jour restent aussi résidents.

Une application de bureau correspond généralement à une famille de processus. Claude Desktop lance sa machine virtuelle isolée ; Codex, un sidecar ; les navigateurs séparent rendu et GPU ; les agents lancent Node, Python, MCP et navigateurs. Un processus isolé dans le moniteur d'activité explique mal l'usage réel. Je regroupe les processus principaux et auxiliaires par famille, puis examine `memory_pressure`, swap, variation du CPU et connexions réseau pour juger les anomalies.

Quatre types de dérive apparaissent.

Les processus et le stockage : une session se termine mais ses enfants restent ; téléchargements, journaux et artefacts grossissent ; l'hôte peut relancer les processus récupérés.

La configuration et le réseau : proxy système, shell, lancement graphique, réglages propres aux applications, DNS et authentification changent séparément.

Les runtimes : Homebrew, installateurs officiels, gestionnaires de versions et anciens projets installent chacun Node, Python ou Rust. PATH choisit finalement le gagnant.

Les ressources de capacités des agents : Skills installés dans différents dossiers, copies qui divergent, liens symboliques cassés, mises à jour amont, frontmatter et chemins codés en dur qui deviennent invalides.

Les trois premières catégories affectent la stabilité d'exécution ; la dernière, l'appel de la bonne capacité. C'est le même problème de gouvernance.

### Le proxy comporte plusieurs couches

C'est la couche où j'ai rencontré le plus de difficultés.

macOS possède plusieurs chemins indépendants. Le proxy système agit sur les applications qui lisent ses réglages. Les variables de `~/.zshrc` ne touchent que le shell et ses enfants. Les processus lancés depuis Finder, Dock ou une application héritent généralement de l'environnement utilisateur `launchd`. Certains navigateurs et CLI ont leurs réglages propres ; TUN, DNS et authentification relèvent d'autres couches.

Un cas typique : le CLI Antigravity fonctionnait dans le terminal, tandis que le même runtime dans Multica signalait une région indisponible. La première correction était une fonction `.zshrc`, limitée au terminal interactif. Le daemon lancé par Multica Desktop depuis l'interface ne lisait pas `.zshrc` et sortait directement sur Internet.

Les preuves utiles venaient des processus actifs. Le daemon n'avait aucune variable de proxy. Les requêtes directes et celles passant par le proxy local sortaient de régions différentes. J'ai finalement déplacé la logique dans un wrapper à l'entrée de l'exécutable, puis simulé un lancement non interactif avec un environnement propre pour vérifier le chemin réel.

J'en ai tiré une règle stable : vérifier le processus cible, pas seulement mon souvenir de la configuration.

Un même outil peut être lancé depuis le terminal, une application, une tâche programmée, MCP ou un autre agent. Son nom ne garantit pas son environnement.

### Un runtime, un propriétaire

L'erreur `tomllib` a révélé quatre Python. conda activait automatiquement `base`, et les agents installaient des paquets dans l'environnement global sans que l'utilisateur s'en rende compte. L'installateur python.org écrivait son PATH dans `.zprofile`, Homebrew conservait d'autres versions, et les tâches non interactives pouvaient choisir celle de macOS.

Rust existait aussi en double : Homebrew en tête du PATH, rustup longtemps sans mise à jour. Pour Node, le problème venait du préfixe global npm. Quand fnm changeait la version, le dossier global changeait aussi, mais un ancien wrapper Claude Code gardait un chemin Homebrew codé en dur. Exécution et mise à jour visaient deux endroits. La commande fonctionnait sans recevoir les bonnes mises à jour.

Après nettoyage, j'ai attribué un propriétaire unique à chaque runtime central.

| Runtime | Propriétaire                                           | Rôle principal                                                 |
| ------- | ------------------------------------------------------ | -------------------------------------------------------------- |
| Node    | [fnm](https://github.com/Schniz/fnm)                   | Versions Node et changement par projet                         |
| Python  | [uv](https://docs.astral.sh/uv/guides/install-python/) | Installation, version de projet, environnements et dépendances |
| Rust    | [rustup](https://rust-lang.github.io/rustup/)          | stable, beta, nightly, versions et composants précis           |

Les runtimes système restent. Ils appartiennent à macOS, ne figurent pas dans mon PATH quotidien et ne portent pas mes dépendances personnelles. Ceux installés par Homebrew pour d'autres formules peuvent rester comme dépendances internes, mais ne doivent pas prendre le point d'entrée utilisateur.

Homebrew convient aux paquets système, CLI stables, applications graphiques et dépendances basses, comme `ripgrep`, `jq`, `ffmpeg`, ainsi qu'à fnm et uv eux-mêmes. Un outil qui ne demande que la version stable actuelle, sans variation par projet, lui convient.

Il faut utiliser directement fnm, uv ou rustup dans ces cas :

1. plusieurs projets exigent des versions majeures ou mineures différentes ;
2. un fichier doit fixer la version du projet ;
3. Rust demande stable, beta, nightly ou une chaîne datée ;
4. les paquets globaux Node changent de préfixe avec la version ;
5. Python doit isoler les dépendances sans polluer le système ou le global ;
6. agents, tâches planifiées et shells non interactifs doivent retrouver la même entrée vérifiable.

Ma règle est simple : Homebrew gère les paquets, les gestionnaires gèrent les langages, les fichiers de projet fixent les versions et PATH n'expose qu'une entrée par défaut.

Avant de retirer l'ancien runtime, mettre à jour et valider le nouveau propriétaire. Pour Rust, compiler et tester avant de supprimer la version Homebrew. Pour Python, vérifier d'abord l'entrée uv dans un environnement propre, puis traiter les doublons conda, python.org et Homebrew. Cet ordre préserve la capacité de travail pendant la gouvernance.

### Deux routines de gouvernance continue

Boris insiste aussi sur la vérification autonome des agents qui travaillent longtemps. Pour une longue tâche, un agent de fond peut vérifier, ou un Stop hook effectuer un contrôle déterministe et renvoyer les échecs à l'agent. Il considère ce retour comme l'un des moyens majeurs d'améliorer la qualité, avec un gain empirique de deux à trois fois. [Billet d'origine](https://x.com/bcherny/status/2007179861115511237).

Il a ensuite décrit le passage du code source aux agents, puis des agents aux boucles continues. L'humain passe de prompts tour par tour à la conception de cycles qui avancent seuls. Dans [son entretien à Meta @Scale](https://www.youtube.com/watch?v=Z47vatpsGPI), il qualifie les boucles de saut tout aussi important.

Une boucle efficace demande objectif, état actuel, vérification et arrêt. Après chaque exécution, l'agent lit le résultat, continue en cas d'échec, et s'arrête lorsque l'objectif est atteint ou qu'une limite de budget ou de risque l'exige. Le Sweeper donne la direction de simplification ; le Loop Engineering la répète.

J'ai créé deux routines dans Claude pour appliquer ces principes.

La première gouverne chaque jour les Skills. Tous les Skills réutilisables rejoignent une même source de vérité sous Git, référencée par liens symboliques depuis Claude Code et Codex. La routine répare liens cassés ou manquants, dossiers vides et déchets de cache. Pour les copies physiques, Skills orphelins, erreurs de frontmatter, mises à jour amont et risques de secrets, elle analyse et signale ; je décide.

La seconde examine chaque semaine les ressources de base du Mac. Elle collecte mémoire, CPU, swap et processus, les regroupe par application et identifie les résidus déjà confirmés. Un processus ne peut être récupéré que s'il dépasse une durée, ne travaille plus au CPU et n'a aucun socket réseau. Seuls les caches reconstruisibles sont nettoyés. Données privées d'application et ressources à propriétaire incertain sont mesurées et signalées.

Les deux suivent les mêmes limites : le script exécute les opérations déterministes sans perte d'information, le modèle analyse ce qui demande un jugement, et l'humain décide des suppressions, remplacements et extensions de droits.

Les nouvelles découvertes rejoignent ensuite Skills, références et Basic Memory. Le tour suivant lit ces sources actualisées, et la capacité de gouvernance s'accumule.

### Rester propre est une capacité d'ingénierie

Je voyais autrefois la configuration du Mac comme un travail ponctuel : installer, régler shell et proxy, puis utiliser.

La fréquence des changements est désormais bien supérieure. Les agents installent des dépendances, lancent des services, créent des caches et Skills, modifient des réglages. Node, Python et Rust évoluent. Applications et CLI suivent des mises à jour distinctes. Proxy et authentification se propagent par différents lancements.

Le Mac a besoin de son plan de contrôle : ressources essentielles, propriétaires, état cible, détection des dérives, actions automatisables et décisions devant s'arrêter.

Le Sweeper soustrait. La boucle rend cette soustraction continue.

Cela ne crée pas immédiatement de fonction nouvelle, mais réduit l'incertitude de chaque exécution future. Les agents ne trouvent plus au hasard de vieilles versions ; terminal et tâches programmées convergent ; les incidents se localisent vite à une couche ; les nouveaux outils savent où s'intégrer.

Pour le Builder, c'est un investissement d'infrastructure à effet composé. Plus l'environnement est stable, plus la boucle dure. Plus la propriété est claire, plus l'automatisation peut recevoir de droits. Plus l'historique est complet, moins le diagnostic suivant doit redécouvrir.

La productivité future viendra ensemble de meilleurs modèles, de meilleurs outils et d'un environnement local durablement explicable, maîtrisable et capable de converger.

Le Builder crée.

Le Sweeper empêche les résidus de cette création de la ralentir.

### Références

* [Boris Cherny sur les cinq rôles de l'équipe Claude Code](https://x.com/bcherny/status/2071379474277613732)
* [Boris Cherny sur les longues tâches et les retours de vérification](https://x.com/bcherny/status/2007179861115511237)
* [Entretien avec Boris Cherny, responsable de Claude Code](https://www.youtube.com/watch?v=Z47vatpsGPI)
* [Versions des formules Homebrew](https://docs.brew.sh/Versions)
* [fnm, Fast Node Manager](https://github.com/Schniz/fnm)
* [Installation et gestion de Python avec uv](https://docs.astral.sh/uv/guides/install-python/)
* [Versions Python dans uv](https://docs.astral.sh/uv/concepts/python-versions/)
* [Le livre de rustup](https://rust-lang.github.io/rustup/)
* [Chaînes d'outils rustup](https://rust-lang.github.io/rustup/concepts/toolchains.html)
