Auf meinem Bildschirm stehen 189,52 GB.
Zwei Nachkommastellen verleihen dieser Zahl eine erstaunliche Autorität. Sie wirkt gemessen, geprüft und abgeschlossen. Daneben zerlegt ein farbiger Balken den belegten Speicher in Apps, Medien, Dateien, Spiele, Entwicklung und Systemdaten. Alles besitzt eine Grösse, eine Farbe und einen festen Platz.
Die Wirklichkeit darunter ist weniger ordentlich.
Manche Dateien teilen sich denselben physischen Speicher. Andere erscheinen vollständig auf dem Mac, obwohl nur ein Platzhalter aus der Cloud vorhanden ist. Bestimmte Verzeichnisse lassen sich nicht lesen. Programme verteilen ihre Daten über zahlreiche Orte, und eine sichtbare Kategorie von wenigen Gigabyte kann Millionen Verzeichniseinträge berühren.
Die Zahl bleibt trotzdem auf zwei Nachkommastellen genau.
Während der Entwicklung von Trace begann ich zu verstehen, dass eine Software mit jeder angezeigten Zahl eine Behauptung aufstellt. Sie sagt dem Benutzer nicht nur, wie gross etwas ist. Sie sagt zugleich: «Du kannst diesem Wert vertrauen.»
Für diese Behauptung genügt keine Berechnung. Die Software muss wissen, wie ein Wert entstanden ist, was darin enthalten ist, was fehlen könnte und was seit seiner Berechnung geschehen ist. Sie muss erkennen, wann ein Ergebnis vollständig, wann es vorläufig und wann es bereits wieder veraltet ist.
Eine Software muss wissen, wann sie recht hat.
Ein Projekt über meiner Erfahrung
Trace war die erste Software, die ich mit Unterstützung künstlicher Intelligenz entwickelte und anschliessend vermarktete. Für ein erstes Produkt hatte ich mir ausgerechnet ein macOS-Systemwerkzeug vorgenommen, das Speicherplatz erklären, Programme mitsamt ihren Rückständen finden, Risiken beurteilen und entfernte Daten bei Bedarf wiederherstellen sollte.
Codex war damals deutlich schwächer als heute. Es verlor häufiger den Zusammenhang, erfand Schnittstellen und löste einzelne Aufgaben, ohne deren Folgen für das Gesamtsystem zu erfassen. Gleichzeitig fehlte mir selbst die Erfahrung mit einer Software dieser Grössenordnung.
Trotzdem entstand ein funktionierendes Produkt.
Trace wurde veröffentlicht und verkauft. Im Februar 2026 stellte iFun die neue Schweizer Mac-App vor und hob ihren Fokus auf Nachvollziehbarkeit hervor. Trace sollte keine pauschalen Löschversprechen abgeben, sondern zeigen, welche Daten Speicher belegen, woher sie stammen und welches Risiko eine Entfernung besitzt.
Wenige Tage später erschien auf Amerpie ein ausführlicher Erfahrungsbericht. Lou Plummer hatte Trace selbst ausprobiert und widersprach der Vermutung, es handle sich um einen weiteren mit KI zusammengewürfelten «Optimizer». Er verwies auf die Dokumentation, die Quarantäne, die Sicherheitsstufen und den Trace Agent. Sein Fazit beschrieb Trace als Diagnoseinstrument für bewusste Entscheidungen.
Diese Artikel hatte ich nicht angeregt. Jemand hatte Trace gefunden, benutzt und für erwähnenswert gehalten. Das bestätigte, dass mein erstes KI-gestütztes Softwareprojekt bereits einen echten Nutzen besass, obwohl ich selbst die Tiefe seines Problems noch nicht vollständig verstanden hatte.
Apples nützliche Unschärfe
Nach der Veröffentlichung blieb Trace nicht stehen. Benutzer wünschten sich weitere Funktionen, während ich selbst mehr Bereiche des Macs verständlich machen wollte. Trace erhielt zusätzliche Kategorien, genauere Zuordnungen, neue Detailansichten, eine Finder-Erweiterung, eine Kommandozeile und bessere Werkzeuge für Entwicklerdaten, Spiele, Cloud-Dateien und Systemdaten.
Mit dem Funktionsumfang wuchs der Anspruch an die Performance.
Die Speicherübersicht von macOS erscheint vergleichsweise schnell. Sie zeigt, wie gross das Laufwerk ist, wie viel Speicher verfügbar bleibt und welche Kategorien einen grossen Anteil belegen. Für die meisten alltäglichen Fragen reicht diese Orientierung aus. Ihre Berechnung bleibt im Hintergrund, und ihre Grenzen werden kaum erklärt.
Diese Unschärfe erfüllt einen Zweck. macOS beantwortet vor allem die praktische Frage, wie viel Speicher das System im Augenblick als verfügbar behandelt. Dafür muss die Anzeige nicht für jedes einzelne Byte offenlegen, welcher Datei es physisch zuzurechnen ist.
Trace stellt eine andere Frage: Welche konkreten Daten belegen den Speicher, woher stammen sie und wie sicher lässt sich ihre Grösse bestimmen?
Apple besitzt zudem einen Vertrauensvorschuss. Weicht Trace von macOS ab, wird der Benutzer kaum zuerst Apples Berechnung hinterfragen. Er vermutet eher einen Fehler in Trace.
Eine genauere Berechnung genügt deshalb nicht. Sie muss sich in einer Welt behaupten, in der bereits eine andere Zahl als Wahrheit gilt.
Auf derselben Oberfläche können damit zwei Wahrheiten nebeneinanderstehen. macOS zeigt die operative Wahrheit des Systems: den Speicher, den es dem Benutzer gegenwärtig zur Verfügung stellt. Trace sucht nach einer analytischen Wahrheit darüber, welche Daten sich einem Ort, einer Kategorie und einer physischen Belegung nachvollziehbar zuordnen lassen.
Die Werte können voneinander abweichen, ohne dass einer von ihnen erfunden ist. Unter derselben Bezeichnung wirken sie dennoch wie ein Widerspruch. Der Benutzer sieht nicht zwei Berechnungsmodelle, sondern zwei Zahlen, von denen eine falsch sein muss.
Trace muss diese Wahrheiten deshalb auseinanderhalten. Die unmittelbar sichtbare Kapazitätsanzeige bleibt mit macOS vergleichbar. Die eigene Präzision gehört in jene Bereiche, in denen Trace ihre Herkunft und ihren Geltungsbereich erklären kann: bei Dateien, Apps, Kategorien und physisch belegtem Speicher.
Eine Datei soll dort gezählt werden, wo sie hingehört. Cloud-Platzhalter dürfen den lokalen Speicher nicht künstlich vergrössern. Gemeinsam belegte Daten müssen vorsichtig behandelt werden. Gelöschte Objekte sollen aus den Ergebnissen verschwinden. Ein Eintrag soll erklären können, weshalb Trace ihn einer App oder Kategorie zugeordnet hat.
Das Produkt braucht Geschwindigkeit, Präzision und Anschluss an die vertraute Anzeige des Betriebssystems. Diese Anforderungen lassen sich nicht mit einer einzigen Zahl erfüllen.
Präzision braucht Zeit
Auf meinem Mac dauerte ein vollständiger Präzisionslauf von Trace mehr als dreieinhalb Stunden. Während dieser Zeit untersuchte die App fast zwanzig Millionen Dateisystemeinträge. Sie bestimmte Grössen, prüfte Zuordnungen, berücksichtigte Hardlinks und APFS-Clones, erkannte Cloud-Zustände und führte die Ergebnisse in einer gemeinsamen Speicherbuchhaltung zusammen.
Für den Benutzer blieb das eine dreieinhalbstündige Wartezeit.
Eine App, die erst nach mehreren Stunden etwas Sinnvolles zeigt, kann rechnerisch vorbildlich und dennoch kaum benutzbar sein. Menschen öffnen eine Speicheranalyse, weil sie jetzt verstehen möchten, weshalb ihr Laufwerk voll ist. Sie wollen keinen halben Arbeitstag warten, bevor sie eine erste Orientierung erhalten.
Eine grobe Schätzung würde das gegenteilige Problem erzeugen. Trace zeigte dann schnell Werte, deren Herkunft und Vollständigkeit ebenso unklar wären wie bei jener Anzeige, die es verständlicher machen wollte.
Der Ausweg liegt in verschiedenen Reifegraden der Information.
Die aktuelle Laufwerkskapazität und der verfügbare Speicher lassen sich sofort anzeigen. Bereits überprüfte Dateien, Apps und Installationen dürfen früh sichtbar werden. Ein früher vollständig berechneter Stand kann beim nächsten Start unmittelbar Orientierung geben. Die umfassende physische Buchhaltung läuft im Hintergrund und ersetzt den bisherigen Stand erst, wenn sie als Ganzes geprüft wurde.
Diese Werte dürfen nicht denselben Status tragen.
Ein Teilresultat beweist nicht, dass Trace bereits alles gefunden hat. Ein gespeicherter Wert ist etwas anderes als ein frisch berechneter. Eine vorhandene Zahl kann weiterhin nützlich sein, während ihre Aktualisierung läuft.
Das kleine Wort «Berechnet» wurde dadurch zu einem Architekturvertrag. Es darf erst erscheinen, wenn Trace nicht nur einen Wert besitzt, sondern dessen Vollständigkeit begründen kann.
Der Cache kennt die Gegenwart nicht
Ein vollständiger Lauf sollte nach dem Schliessen der App nicht wertlos werden. Deshalb speicherte Trace seine Ergebnisse.
Der Cache löste das Geschwindigkeitsproblem zunächst überzeugend. Beim nächsten Start erschienen die Werte sofort. Eine gespeicherte Zahl trägt jedoch keine Erinnerung an das, was danach geschah.
Der Benutzer kann Dateien löschen, verschieben oder herunterladen. Programme erzeugen neue Caches. Spiele installieren Updates. Cloud-Dienste laden Daten lokal oder geben sie wieder frei. Externe Laufwerke werden getrennt. Eine App kann gestern 20 GB belegt haben und heute nur noch 8 GB.
Aus diesem Performanceproblem entstand der Watcher.
Er berechnet nicht fortlaufend den gesamten Speicher neu. Der Watcher beobachtet Veränderungen und merkt sich, welchen früheren Aussagen Trace inzwischen nicht mehr vorbehaltlos vertrauen darf. Solange diese Aufzeichnung lückenlos bleibt, kann Trace unveränderte Kategorien aus dem letzten Präzisionslauf sofort anzeigen und nur die betroffenen Bereiche erneut untersuchen.
Die mehrstündige Analyse wird damit zu einer Investition, deren Ergebnisse über mehrere Starts hinweg nutzbar bleiben.
Für den Benutzer wäre ein eigener Watcher jedoch ein schlechter Handel gewesen. Ein zusätzlicher Hintergrundprozess hätte Arbeitsspeicher und Rechenzeit beansprucht, nur damit Trace beim nächsten Öffnen schneller erscheint. Der unmittelbare Nutzen läge bei der App, die laufenden Kosten beim Benutzer.
Der Trace Agent existierte bereits. Wenn jemand eine App in den Papierkorb verschob, erkannte er die Aktion, suchte nach zugehörigen Rückständen und bot deren kontrollierte Entfernung an. Diese Funktion hatte einen direkten Wert, solange der Agent im Hintergrund lief.
Ich integrierte den Watcher deshalb in den bestehenden Agent. Derselbe Hintergrundprozess erfüllt nun zwei Aufgaben: Er hilft dem Benutzer unmittelbar beim vollständigen Entfernen einer App und hält zugleich jene Veränderungen fest, die für spätere Speicheranalysen wichtig sind.
So entstand ein fairer Tausch. Der Benutzer lässt den Agent freiwillig laufen, weil er ihm im Alltag hilft. Trace erhält dadurch die zeitliche Kontinuität, die für schnelle und trotzdem belastbare Ergebnisse nötig ist.
Als die Zeit Teil der Daten wurde
Vor dem Watcher folgte Trace einem überschaubaren Modell: Die App startete eine Analyse, berechnete Werte und zeigte sie an.
Danach musste sie über Tage, Neustarts und mehrere Prozesse hinweg beurteilen, welche früheren Aussagen noch galten. Zeit wurde Teil des Datenmodells.
Was geschieht, wenn der Watcher einige Stunden nicht läuft? Wie behandelt Trace eine Datei, die verschoben statt gelöscht wurde? Was passiert, wenn ein externes Laufwerk fehlt, eine Analyse abbricht oder die App während einer Berechnung beendet wird? Darf ein alter Wert sichtbar bleiben, während ein neuer entsteht? Welche Kategorien müssen nach einer Änderung erneut geprüft werden?
Die ursprüngliche Architektur besass dafür keine gemeinsame Antwort.
Das zeigte sich zunächst in einzelnen Fehlern. Eine Verbesserung beschleunigte den Start, liess aber alte Tabellenzeilen stehen. Ein gezielter Kategorienlauf löste versehentlich eine vollständige Analyse aus. Eine strengere Cacheprüfung verwarf Ergebnisse, die noch gültig waren. Ein Detailauftrag lief ab, während er lediglich auf einen anderen Scanner wartete. Eine Kategorie zeigte einen abgeschlossenen Zustand, obwohl nur ein begrenztes Resultat vorlag.
Jede Korrektur wirkte an ihrer Stelle vernünftig. Im Gesamtsystem verschob sie häufig den Widerspruch.
Scanner, Cache, Kategorien, Tabellen und Hintergrundprozesse besassen unterschiedliche Vorstellungen davon, was «aktuell», «vollständig» und «berechnet» bedeutete. Die Software verfügte über viele Werte, aber über keine gemeinsame Sprache für deren Gültigkeit.
Das Iterieren begann sich im Kreis zu drehen. Ein weiterer lokaler Patch hätte nur eine weitere Ausnahme geschaffen. Ich musste die Speicherarchitektur noch einmal vom Fundament her entwerfen.
Unbekannt ist nicht leer
Ein leerer Eintrag kann sehr unterschiedliche Dinge bedeuten. Vielleicht hat Trace den Bereich geprüft und nichts gefunden. Vielleicht begann die Suche noch nicht. Vielleicht fehlen Berechtigungen. Vielleicht wurde ein früheres Ergebnis ungültig. Vielleicht läuft gerade eine neue Analyse.
Wer diese Zustände nicht ausdrücklich modelliert, zwingt den Code zu Vermutungen.
Dann wird «kein Wert» irgendwann mit null gleichgesetzt. Eine leere Tabelle erscheint als «Keine Ergebnisse», obwohl die Suche noch läuft. Ein Cache gilt als aktuell, weil kein besserer Zustand vorgesehen ist. Ein Teilresultat erhält denselben Status wie eine abgeschlossene Analyse.
Unbekannt ist nicht leer.
Der neue Architekturplan musste deshalb für alle Kategorien und Detailansichten festlegen, welche Herkunft ein Ergebnis besitzt, welche Voraussetzungen dafür gelten und wodurch es seine Gültigkeit verliert. Ein vollständiger Lauf erzeugt einen zusammenhängenden Stand. Der Cache darf ihn wiederverwenden, solange seine Beweiskette erhalten bleibt. Der Watcher markiert betroffene Bereiche. Eine unterbrochene Überwachung erzeugt eine Lücke, die Trace nicht mit einer plausiblen Annahme überdecken darf.
Auch die Sonderfälle wurden Teil des Ausgangspunkts: verlorene Watcher-Abdeckung, Cloud-Platzhalter, externe Laufwerke, Hardlinks, APFS-Clones, unterbrochene Analysen, wiederholte Aktualisierungen und Ergebnisse, deren Existenz belegt, deren Vollständigkeit aber noch offen ist.
Ein wasserdichtes Konzept muss nicht jede zukünftige Situation vorhersehen. Es muss bekannte Zustände eindeutig behandeln und bei einem unbekannten Zustand vorsichtig bleiben.
Ein System darf etwas noch nicht wissen. Es muss diesen Zustand erkennen können.
Benutzerfreundlichkeit als Übersetzung von Gewissheit
Ich betrachtete Benutzerfreundlichkeit lange vor allem als Frage der Bedienung. Eine Oberfläche sollte verständlich aussehen, kurze Wege bieten und den Benutzer nicht mit unnötigen Entscheidungen belasten.
Trace hat diese Vorstellung erweitert.
Eine benutzerfreundliche Software muss früh handlungsfähig machen. Dafür braucht der Benutzer Informationen, bevor im Hintergrund jede Prüfung abgeschlossen ist. Die Oberfläche darf dabei keine Sicherheit vorspiegeln, die das System noch nicht besitzt.
Der Benutzer soll keine internen Generationen, Watcher-Abdeckungen oder Cache-Verträge verstehen müssen. Er muss trotzdem erkennen können, ob ein Wert aktuell, gespeichert, im Aufbau oder unvollständig ist. Eine früh gefundene Datei darf erscheinen, während die Suche weiterläuft. Trace darf daraus noch nicht ableiten, dass bereits alle Dateien gefunden wurden. Ein früher bestätigter Wert kann während einer Aktualisierung sichtbar bleiben, solange seine Herkunft nicht verschwiegen wird.
«Keine Ergebnisse» darf erst erscheinen, wenn Trace tatsächlich gesucht und nichts gefunden hat. «Berechnet» bleibt einem Zustand vorbehalten, dessen Voraussetzungen erfüllt sind.
Die Oberfläche beseitigt technische Unsicherheit nicht. Sie gibt ihr eine Form, die ein Mensch verstehen kann.
Darin liegt die schwierigste Balance von Trace. Die App soll sich so unmittelbar anfühlen wie Apples Speicherübersicht und zugleich ehrlicher mit den Grenzen ihrer Aussagen umgehen. Ein ruhiges Interface entsteht in einem solchen System nicht durch geringe Komplexität. Es entsteht, weil die Software diese Komplexität selbst trägt.
Was KI wirklich beschleunigt
Als ich Trace begann, fehlte mir die Erfahrung mit einem Projekt dieser Grössenordnung. Codex war weniger leistungsfähig und verlor häufiger den Zusammenhang. Trotzdem entstand eine Software, die funktionierte, verkauft wurde und öffentliche Anerkennung erhielt.
KI half mir, Oberflächen, Scanner, Tests und Systemkomponenten aufzubauen. Sie machte es möglich, Varianten auszuprobieren, Sackgassen zu verwerfen und ganze Bereiche erneut zu entwickeln, ohne dass jeder Versuch Wochen kostete.
Generative KI machte dabei eine ältere Wahrheit der Softwareentwicklung sichtbar. Programmierkompetenz wurde nie daran gemessen, wie viele Zeichen jemand ohne Dokumentation oder fremde Vorarbeit aus dem Gedächtnis schreiben kann. Software entstand schon immer auf höheren Abstraktionsebenen: Sprachen bauten auf Maschinencode auf, Frameworks auf Bibliotheken und Anwendungen auf Komponenten, deren Innenleben die meisten Entwickler weder lesen noch selbst nachbauen würden.
Der Einsatz von KI verschiebt diese Abstraktion noch einmal. Damit wird Autorschaft leicht mit Kompetenz verwechselt. Für Trace war jedoch nicht entscheidend, ob jede Codezeile unmittelbar von mir stammte. Ich musste das Problem verstehen, eine plausible Lösung beurteilen, ihre Grenzen erkennen und bemerken, wenn sie nicht mehr zum Gesamtsystem passte. Ein blind übernommenes KI-Ergebnis beweist ebenso wenig Kompetenz wie ein kopierter Codeausschnitt oder eine unverstandene Framework-Funktion.
Der Engpass verlagerte sich vom Tippen zum Entscheiden.
Eine Codex-Instanz kann eine lokale Aufgabe überzeugend lösen. Die nächste entwickelt möglicherweise eine ebenso überzeugende, leicht abweichende Vorstellung derselben Architektur. Beide Lösungen wirken für sich vernünftig und erzeugen gemeinsam einen Widerspruch.
Ohne schriftliche Regeln entstehen mehrere plausible Wirklichkeiten nebeneinander.
In meinem Essay über AI-Slop schrieb ich, dass Erzeugen billig geworden ist, Bauen aber nicht. Trace hat mir diese Unterscheidung praktisch beigebracht.
Je leistungsfähiger die KI wurde, desto wichtiger wurden jene Dinge, die sie nicht bei jeder Aufgabe neu festlegen durfte: die Bedeutung eines Zustands, die Grenzen einer Komponente, die Voraussetzungen eines Ergebnisses und der Nachweis, dass eine Änderung wirklich funktioniert.
KI lieferte mir keine fertige Erfahrung. Sie gab mir genug Umsetzungskraft, früh auf Probleme zu treffen, aus denen Erfahrung entsteht.
Architektur als Gedächtnis
Ich hätte Trace an vielen Stellen als «gut genug» betrachten können. Die App funktionierte, wurde verkauft und positiv besprochen. Die verbliebenen Widersprüche wären für viele Benutzer zunächst unsichtbar geblieben.
Ein alter Wert hätte eine zusätzliche Sonderregel erhalten. Ein unvollständiger Zustand wäre durch eine vorsichtige Formulierung kaschiert worden. Ein globaler Scan hätte weiterhin Arbeit ausgeführt, die niemand bewusst angefordert hatte. Jeder neue Fehler hätte einen weiteren Patch bekommen.
Die Software hätte weiter funktioniert. Mit der Zeit wäre jedoch immer schwerer zu erklären gewesen, weshalb.
Mein Qualitätsanspruch zwang mich, hinter dem sichtbaren Fehler nach seiner Ursache zu suchen. Dadurch lernte ich weit mehr als Swift oder SwiftUI. Ich musste mich mit Dateisystemen, Cloud-Zuständen, Berechtigungen, Nebenläufigkeit, Prozessgrenzen, Persistenz und der Gültigkeit gespeicherter Ergebnisse beschäftigen.
Aus wiederkehrenden Fehlern entstanden Regeln. Die Regeln wurden zu Tests. Die Tests machten sichtbar, wo die Architektur noch widersprüchlich war.
Eine Architektur ist mehr als ein Plan vor dem ersten Code. Sie ist das verdichtete Gedächtnis eines Projekts. In ihr steckt, welche Annahmen sich bewährt haben, welche Irrtümer teuer waren und welche Zustände nie wieder verwechselt werden dürfen.
Das gilt in einem KI-gestützten Projekt besonders. Jede neue Instanz beginnt mit begrenztem Kontext. Die Architektur vermittelt ihr, welche Bedeutungen bereits ausgehandelt wurden. Sie schützt das System davor, dieselben plausiblen Irrtümer immer wieder neu zu erfinden.
Das Projekt, das zurückfragte
Ich begann mit einer Software, die dem Benutzer sagen sollte, was seinen Speicher belegt.
Mit der Zeit stellte das Projekt dieselbe Frage an mich zurück:
Woher weisst du das?
Diese Frage veränderte meine Arbeit.
Eine Zahl ist nicht vertrauenswürdig, weil sie präzise aussieht. Sie wird vertrauenswürdig, wenn das System ihre Herkunft kennt, ihre Grenzen versteht und bemerkt, sobald ihre Voraussetzungen nicht mehr gelten.
Dasselbe gilt für Software als Ganzes. Ein Programm wird belastbar, wenn es auch mit Unterbrüchen, fehlenden Informationen, widersprüchlichen Zuständen und einer Wirklichkeit umgehen kann, die sich während seiner eigenen Berechnung verändert.
Trace war für mein erstes Softwareprodukt viel zu gross. Gerade dadurch wurde es zu einer ungewöhnlich wirksamen Ausbildung. Ein kleineres Projekt hätte mir viele Schwierigkeiten erspart und wesentlich weniger beigebracht.
KI machte es möglich, ein Vorhaben zu beginnen, dessen Tragweite ich damals noch nicht überblickte. Mein Qualitätsanspruch verhinderte, dass ich beim ersten funktionierenden Zustand stehen blieb. Zwischen diesen beiden Kräften lernte ich das Bauen.
Ich wollte eine Software entwickeln, die erklärt, was einen Mac belegt.
Am Ende musste ich eine Software bauen, die weiss, wann sie diese Erklärung geben darf.