> 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/de/2026/w32-a-builders-mac-also-needs-a-sweeper.md).

# W32-Auch der Mac eines Builders braucht einen Sweeper

Ich habe drei Macs. Mein wichtigstes Arbeitsgerät ist derzeit ein Mac Studio mit M2 Max, einer CPU mit zwölf Kernen und 64 GB Arbeitsspeicher. Daran hängen ein 5K-Bildschirm und ein Shure-MV7+-Mikrofon.

An Hardware fehlt es kaum. Die alltäglichen Engpässe liegen eher in der Softwareumgebung. Codex, Claude Code, ChatGPT, Antigravity und Multica laufen langfristig parallel. Dahinter starten Browser, MCP-Server, Sidecars, Sandbox-VMs und verschiedene Unterprozesse. Auch Node, Python, Rust, Proxys, Skills, Startobjekte und Caches ändern sich laufend.

Die letzte Aufräumaktion begann mit einem kleinen Fehler. Die täglich automatisch ausgeführte Skill-Verwaltung meldete `ModuleNotFoundError: No module named 'tomllib'`. Die Untersuchung zeigte, dass das interaktive Terminal und die geplante Aufgabe verschiedene Python-Versionen aufriefen. Auf dem Mac existierten gleichzeitig das System-Python, Homebrew-Python, eine Installation von python.org und conda. Ähnliche Probleme gab es bei Node und Rust.

Wenn solche lokalen Probleme zusammenkommen, wird die Umgebung zunehmend unverständlich. Befehle zeigen gelegentlich auf alte Versionen, die Zugehörigkeit von Hintergrundprozessen ist unklar, dieselbe Aufgabe klappt im Terminal und scheitert im Zeitplan. Je schneller Agents handeln, desto schneller driftet auch die Umgebung auseinander.

Ich betrachte den Mac inzwischen als Produktionssystem eines Builders. Er braucht laufende Pflege und klare Regeln.

### Builder müssen auch Sweeper sein

Boris Cherny hat die Arbeit im Claude-Code-Team kürzlich in fünf Rollen eingeteilt: Prototyper, Builder, Sweeper, Grower und Maintainer. Builder machen aus Prototypen produktionsfähige Produkte und Infrastruktur. Sweeper räumen Oberflächen auf, vereinfachen Systeme, entfernen wertlos gewordene Funktionen und verbessern die Leistung. [Boris’ Originalbeitrag](https://x.com/bcherny/status/2071379474277613732) zeigt Rollenkombinationen für verschiedene Produktphasen. Der Sweeper kommt in jeder Phase vor.

Das passt gut zu meinen jüngsten Erfahrungen.

Agents sind von Natur aus gut darin, Dinge hinzuzufügen. Sie installieren Werkzeuge, erzeugen Code, ergänzen Konfigurationen und erstellen Skills. Die Grenzkosten des Hinzufügens sind bereits sehr niedrig. Entfernen und Vereinheitlichen verlangen weiterhin Urteilskraft. Was hat keinen Wert mehr? Welche Kopien gehören zusammen? Welche Laufzeit soll den maßgeblichen Einstiegspunkt besitzen? Welche automatisierten Aktionen könnten gültigen Zustand löschen? Dafür braucht es einen Sweeper.

Für einen einzelnen Builder gehört auch die lokale Umgebung zu dessen Aufgaben. Prozesse, Caches, Laufzeiten, Proxykonfigurationen, Startobjekte, Skills und Agent-Konfigurationen sind Ressourcen. Sie hängen voneinander ab und verändern sich mit der Nutzung.

Eine saubere Umgebung hat für mich vier Eigenschaften: Wichtige Einstiegspunkte haben klare Eigentümer, laufende Komponenten lassen sich erklären, Abweichungen werden sichtbar und das System kann in einen bekannten Zustand zurückkehren.

### Welche Ressourcen auf dem Mac existieren

Meine wichtigsten Arbeitsoberflächen sind Codex, Claude Code, ChatGPT, Antigravity und Multica. Im Terminal nutze ich Ghostty und cmux. Für Wissen verwende ich vor allem Basic Memory und Craft. Craft speichert Notizen, Artikel und aufbereitete Ergebnisse für Menschen. Basic Memory speichert stabile Erkenntnisse, wiederverwendbare Abläufe und Kontext, den Agents fortlaufend abrufen können.

Browser und Automatisierung starten Chrome, Playwright und MCP-Server. Unternehmenssicherheitssoftware, Proxywerkzeuge, Eingabemethoden, Synchronisationsdienste und App-Updater bleiben ebenfalls dauerhaft aktiv.

Eine Desktop-App entspricht meist einer ganzen Prozessgruppe. Claude Desktop startet eine eigene Sandbox-VM, Codex einen Sidecar, Browser teilen Renderer und GPU-Prozesse ab, und Agent-Werkzeuge starten Node-, Python-, MCP- und Browser-Unterprozesse. Ein einzelner Prozess in der Aktivitätsanzeige erklärt den tatsächlichen Ressourcenverbrauch kaum. Ich fasse deshalb Hauptprozesse und Helper nach App-Familien zusammen und beurteile Auffälligkeiten anhand von `memory_pressure`, Swap, CPU-Zuwachs und Netzwerkverbindungen.

Bei diesen Ressourcen gibt es vier Arten von Abweichungen.

Erstens bei Prozessen und Speicherplatz. Eine Sitzung ist beendet, ihre Unterprozesse laufen weiter. Download-Caches, Protokolle und Build-Artefakte wachsen. Die Host-App startet möglicherweise bereits beendete Prozesse immer wieder neu.

Zweitens bei Konfiguration und Netzwerk. Systemproxy, Shell-Umgebung, GUI-Startumgebung, appinterne Proxyeinstellungen, DNS und Authentifizierungszustand können sich unabhängig voneinander ändern.

Drittens bei Laufzeiten. Homebrew, offizielle Installer, Versionsmanager und alte Projekte installieren jeweils Node, Python oder Rust. Am Ende entscheidet PATH, was tatsächlich verwendet wird.

Viertens bei den Fähigkeiten der Agents. Verschiedene Werkzeuge installieren Skills in verschiedene Verzeichnisse. Physische Kopien entwickeln sich auseinander, symbolische Links brechen, Upstream-Versionen ändern sich und Frontmatter oder fest codierte Pfade funktionieren nicht mehr.

Die ersten drei Arten beeinflussen den stabilen Programmbetrieb. Die vierte beeinflusst, ob Agents die richtigen Fähigkeiten aufrufen. Sie gehören zum selben Verwaltungsproblem.

### Proxys bilden eine mehrschichtige Umgebung

Die Proxyumgebung hat mich am längsten beschäftigt.

Unter macOS gibt es mehrere voneinander unabhängige Proxywege. Der Systemnetzwerkproxy beeinflusst Apps, die macOS-Einstellungen lesen. Proxyvariablen in `~/.zshrc` gelten nur für die jeweilige Shell und ihre Kinder. Prozesse, die aus Finder, Dock oder Desktop-Apps starten, erben normalerweise die Umgebung des Benutzer-`launchd`. Manche Browser und CLIs besitzen eigene Proxyeinstellungen. TUN, DNS und Authentifizierung liegen wieder auf anderen Ebenen.

Ich hatte einen typischen Fall: Die Antigravity-CLI funktionierte im Terminal bereits, dieselbe Runtime meldete in Multica weiter, die Region werde nicht unterstützt. Die erste Reparatur steckte in einer `.zshrc`-Funktion und erfasste deshalb nur interaktive Terminals. Multica Desktop startet seinen Daemon über die GUI, liest `.zshrc` nicht und ging am Ende direkt ins Netz.

Die entscheidenden Belege kamen aus dem laufenden Prozess. In der Umgebung des Multica-Daemons fehlten Proxyvariablen. Direkte Anfragen und Anfragen über den lokalen Proxy hatten unterschiedliche Ausgangsregionen. Schließlich legte ich die Proxylogik in einen Wrapper am ausführbaren Einstiegspunkt und simulierte einen nicht interaktiven Start mit bereinigter Umgebung. So bestätigte ich, dass der tatsächliche Aufrufweg wirksam war.

Aus dieser Untersuchung entstand eine feste Regel: Ich muss den Zielprozess prüfen, nicht nur meine Vorstellung davon, was ich konfiguriert habe.

Dasselbe Werkzeug kann aus einem Terminal, einer Desktop-App, einer geplanten Aufgabe, einem MCP oder einem anderen Agent starten. Ein gleicher Name bedeutet keine gleiche Laufzeitumgebung.

### Jede Laufzeit braucht genau einen Eigentümer

Der `tomllib`-Fehler brachte letztlich vier Python-Installationen ans Licht. conda aktivierte `base` automatisch, und Agents installierten unbemerkt Pakete in die globale Umgebung. Der python.org-Installer schrieb seinen eigenen PATH in `.zprofile`, Homebrew hielt weitere Python-Versionen bereit, und nicht interaktive Aufgaben konnten zuerst die macOS-Version treffen.

Auch Rust war doppelt vorhanden. Homebrews Rust stand vorne im PATH, während die von rustup verwaltete Version lange nicht aktualisiert worden war. Bei Node lag das Problem am globalen npm-Prefix. Wenn fnm die Node-Version wechselte, änderte sich auch das globale npm-Installationsverzeichnis. Der alte Claude-Code-Wrapper war aber weiterhin fest auf einen Homebrew-Pfad eingestellt. Ausführungs- und Update-Einstieg zeigten auf zwei Orte. Der Befehl lief, erhielt jedoch nicht die richtigen Updates.

Nach dem Aufräumen gab ich jeder der drei zentralen Laufzeiten einen einzigen Eigentümer.

| Laufzeit | Eigentümer                                             | Hauptaufgabe                                                                                       |
| -------- | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
| Node     | [fnm](https://github.com/Schniz/fnm)                   | Node-Versionen verwalten und je Projekt wechseln                                                   |
| Python   | [uv](https://docs.astral.sh/uv/guides/install-python/) | Python installieren, Projektversionen festlegen, Umgebungen erstellen und Abhängigkeiten verwalten |
| Rust     | [rustup](https://rust-lang.github.io/rustup/)          | stable, beta, nightly, bestimmte Versionen und Komponenten verwalten                               |

Die systemeigenen Laufzeiten bleiben erhalten. Sie gehören zu macOS, stehen nicht in meinem alltäglichen PATH und tragen keine Abhängigkeiten persönlicher Projekte. Von Homebrew als Abhängigkeit anderer Formulas installierte Sprachlaufzeiten können intern weiterbestehen. Sie sollten aber nicht den Benutzereinstieg übernehmen.

Homebrew eignet sich für systemweite Pakete, stabile CLIs, GUI-Apps und grundlegende Abhängigkeiten wie `ripgrep`, `jq` und `ffmpeg` sowie für Versionsmanager wie fnm und uv selbst. Braucht ein Werkzeug nur die aktuelle stabile Version und keinen projektbezogenen Wechsel, passt es zu Homebrew.

In folgenden Fällen sollten direkt fnm, uv oder rustup zuständig sein:

1. Mehrere Projekte benötigen unterschiedliche Major- oder Minor-Versionen.
2. Ein Projekt muss seine Laufzeit über eine Versionsdatei festlegen.
3. Rust braucht stable, beta, nightly oder eine Toolchain eines bestimmten Datums.
4. Bei globalen Node-Paketen ändert sich der Prefix mit der Version.
5. Python muss Projektabhängigkeiten isolieren, damit sie weder System noch globale Umgebung verunreinigen.
6. Agents, geplante Aufgaben und nicht interaktive Shells müssen denselben überprüfbaren Einstieg auflösen.

Meine Regel ist einfach: Homebrew verwaltet Pakete, Versionsmanager verwalten Sprachen, Projektdateien verwalten Versionen, und PATH bietet genau einen Standardeinstieg an.

Vor dem Entfernen alter Laufzeiten wird zuerst der neue Eigentümer aktualisiert und geprüft. Bei Rust kam erst ein Kompilierungstest, dann die Entfernung von Homebrew-Rust. Bei Python prüfte ich zuerst, ob uvs Standardeinstieg in einer bereinigten Umgebung funktioniert. Erst danach kümmerte ich mich um doppelte Installationen von conda, python.org und Homebrew. Diese Reihenfolge schützt die aktuelle Arbeitsfähigkeit während der Bereinigung.

### Zwei Routinen für die laufende Pflege

Boris betont auch wiederholt, dass lange laufende Agents ihre eigene Arbeit prüfen können müssen. Bei sehr langen Aufgaben kann ein Hintergrund-Agent die Prüfung übernehmen. Alternativ führt ein Stop-Hook deterministische Prüfungen aus und gibt Fehlschläge zur weiteren Bearbeitung an den Agent zurück. Er betrachtet solche Rückmeldungen als eines der wichtigsten Mittel für bessere Ergebnisse und nennt aus Erfahrung eine Verbesserung um das Zwei- bis Dreifache. [Originalbeitrag](https://x.com/bcherny/status/2007179861115511237)

Später beschrieb er den Wandel als Übergang vom Quellcode zum Agent und vom Agent zum dauerhaft laufenden Loop. Auch die menschliche Arbeit verschiebt sich: weg vom Schreiben einzelner Prompts, hin zum Entwurf von Schleifen, die selbst vorankommen. Im [Gespräch bei Meta @Scale](https://www.youtube.com/watch?v=Z47vatpsGPI) nennt Boris Loops einen ebenso wichtigen Entwicklungssprung.

Ein wirksamer Loop braucht mindestens ein klares Ziel, den aktuellen Zustand, Prüfrückmeldungen und eine Abbruchbedingung. Der Agent liest nach jeder Runde die Ergebnisse und arbeitet bei fehlgeschlagenen Prüfungen weiter. Er stoppt, wenn das Ziel erreicht ist oder Budget- und Risikogrenzen greifen. Der Sweeper gibt die Richtung für fortlaufenden Abbau vor. Loop Engineering sorgt dafür, dass es wiederholt geschieht.

Ich habe in Claude zwei Routinen eingerichtet, die diese Prinzipien in den Alltag übersetzen.

Die erste verwaltet täglich Skills. Alle wiederverwendbaren Skills liegen in einer gemeinsamen, mit Git verwalteten maßgeblichen Quelle. Claude Code und Codex greifen über symbolische Links darauf zu. Die Routine repariert kaputte Links, leere Verzeichnishüllen, Cache-Müll und fehlende Verknüpfungen automatisch. Bei physischen Kopien, verwaisten Skills, Frontmatter-Fehlern, Upstream-Updates oder Risiken für Zugangsdaten analysiert und berichtet sie nur. Die Entscheidung bleibt bei mir.

Die zweite prüft wöchentlich die grundlegenden Mac-Ressourcen. Sie erfasst zunächst Arbeitsspeicher, CPU, Swap und Prozesszustände, bündelt Ressourcen nach App-Familien und sucht nach bestätigten Mustern zurückgebliebener Prozesse. Ein Prozess darf nur entfernt werden, wenn er zugleich eine Mindestlebensdauer überschritten hat, keine CPU-Arbeit leistet und keine Netzwerksockets besitzt. Die Cache-Bereinigung umfasst nur wiederherstellbare Inhalte. Appinterne Daten und Ressourcen unklarer Zugehörigkeit werden nur gemessen und gemeldet.

Beide Routinen halten dieselbe Grenze ein: Skripte erledigen deterministische Aktionen ohne Informationsverlust, das Modell analysiert Fälle mit Urteilsbedarf, und Menschen entscheiden über Löschen, Überschreiben und zusätzliche Rechte.

Neue Erkenntnisse jeder Runde fließen außerdem in Skills, Referenzen und Basic Memory zurück. Die nächste Runde liest die aktualisierte maßgebliche Quelle. So wächst die Fähigkeit zur Pflege laufend weiter.

### Dauerhafte Ordnung ist eine technische Fähigkeit

Früher hielt ich die Einrichtung meines Macs für eine einmalige Aufgabe: Software installieren, Shell und Proxy konfigurieren und dann losarbeiten.

Heute verändert sich die Umgebung erheblich schneller. Agents installieren Abhängigkeiten, starten Dienste, erzeugen Caches und Skills und ändern Konfigurationen. Node, Python und Rust entwickeln sich laufend weiter. Desktop-Apps und CLIs haben verschiedene Updatewege; Proxy- und Authentifizierungszustände verbreiten sich über unterschiedliche Startpfade.

Der Mac braucht eine eigene Steuerungsebene. Sie muss wissen, welche zentralen Ressourcen existieren, wem sie gehören, wie ihr Zielzustand aussieht, wie sich Abweichungen erkennen lassen, welche Aktionen automatisch laufen dürfen und bei welchen Entscheidungen sie anhalten muss.

Der Sweeper übernimmt das Reduzieren. Der Loop sorgt dafür, dass es fortlaufend geschieht.

Kurzfristig entstehen dabei keine neuen Funktionen. Doch die Unsicherheit jeder künftigen Ausführung sinkt. Agents treffen nicht mehr zufällig alte Versionen, geplante Aufgaben und Terminalaufrufe liefern leichter übereinstimmende Ergebnisse, Fehler lassen sich rasch einer bestimmten Umgebungsebene zuordnen, und neue Werkzeuge wissen, an welchen Einstieg sie gehören.

Für Builder ist das eine Infrastrukturinvestition mit Zinseszinseffekt. Je stabiler die Umgebung, desto länger können Agent-Loops laufen. Je klarer die Zuständigkeit, desto mehr Befugnisse kann Automatisierung erhalten. Je vollständiger die Pflegeprotokolle, desto weniger muss bei der nächsten Störung erneut entdeckt werden.

Künftige Produktivität entsteht aus stärkeren Modellen, besseren Werkzeugen und einer lokalen Umgebung, die langfristig erklärbar bleibt, sich in einen definierten Zustand zurückführen und kontrollieren lässt.

Builder schaffen Neues.

Sweeper sorgen dafür, dass die Überreste dieser Arbeit das Schaffen nicht ausbremsen.

### Quellen

* [Boris Chernys Originalbeitrag zu den fünf Rollen im Claude-Code-Team](https://x.com/bcherny/status/2071379474277613732)
* [Boris Chernys Originalbeitrag zu langen Aufgaben und Prüfrückmeldungen](https://x.com/bcherny/status/2007179861115511237)
* [Gespräch mit Boris Cherny, Leiter von Claude Code](https://www.youtube.com/watch?v=Z47vatpsGPI)
* [Versionen von Homebrew-Formulas](https://docs.brew.sh/Versions)
* [fnm (Fast Node Manager)](https://github.com/Schniz/fnm)
* [uv-Dokumentation zur Installation und Verwaltung von Python](https://docs.astral.sh/uv/guides/install-python/)
* [uv-Dokumentation zu Python-Versionen](https://docs.astral.sh/uv/concepts/python-versions/)
* [Das rustup-Handbuch](https://rust-lang.github.io/rustup/)
* [rustup-Dokumentation zu Toolchains](https://rust-lang.github.io/rustup/concepts/toolchains.html)
