Steven
Steven7 Min. Lesezeit

Was eine Version 2 wirklich kostet: 206 Commits ehrlicher Zustände

Die v2 von GeekBye war kein Feature-Release. Es waren 206 Commits, die auf eine einzige Idee zielten: Die App darf niemals über ihren eigenen Zustand lügen. Das ist der Preis dafür — inklusive des Ein-Zeilen-Fehlers im Lockfile, der uns fast daran gehindert hätte, überhaupt etwas auszuliefern.

Zuverlässigkeit
Engineering
Release
GeekBye-Releases
Was eine Version 2 wirklich kostet: 206 Commits ehrlicher Zustände

Die meisten „Version 2"-Releases sind ein Haufen neuer Features mit einer größeren Zahl obendrauf. Die v2 von GeekBye war das Gegenteil. Sie brachte fast keine neue, für Nutzer sichtbare Fähigkeit. Ihre 206 Commits zielten auf eine einzige, unglamouröse Idee:

Die App darf dir niemals einen Zustand zeigen, der nicht wahr ist.

Das klingt selbstverständlich, bis man zählt, auf wie viele Arten eine Desktop-App still lügt. Sie zeigt ein Häkchen bei einem Upload, der noch unterwegs ist. Sie sagt „verbunden" über einen Socket, der vor einer Minute gestorben ist. Sie schweigt, während dein Transkript einfach fallen gelassen wird. Nichts davon ist ein Absturz. Es ist schlimmer als ein Absturz, denn die App sieht in Ordnung aus, während sie falsch liegt — und du merkst es erst später, wenn die Aufnahme, die du brauchtest, nicht da ist.

Die v2 war das Release, in dem wir auf die Jagd nach jeder einzelnen dieser kleinen Lügen gingen.

Die Lüge, die wir am meisten hassten: der Upload, der „geklappt hat"

GeekBye kann deine Aufnahmen in Google Drive sichern. In der v1 wurde die Verbindung zu Drive als Hintergrunddetail behandelt — wenn sie funktionierte, gut; wenn nicht, war der Fehler weitgehend unsichtbar. Die App sah weiterhin verbunden aus. Du gingst davon aus, dass deine Aufnahmen sicher waren. Manchmal waren sie es nicht.

Die v2 baute das um ehrliche Verbindungszustände herum neu auf. Drive ist jetzt immer in einem von wenigen expliziten, wahrhaftigen Zuständen — verbunden, verbindet erneut, getrennt — und die App sendet jede Änderung dieses Zustands im selben Moment, in dem sie passiert, an die gesamte Oberfläche. Wenn die Verbindung weg ist, sagt dir ein globales Reconnect-Banner das, überall, klar und deutlich. Die App tut nicht mehr so, als sei ein Upload gelungen, wenn er es nicht war. Wenn dein Backup gerade nicht stattfinden kann, weißt du es jetzt — nicht nächste Woche, wenn du die Datei suchst.

Darunter ist das eine kleine Architektur, kein Slogan: eine einzige Quelle der Wahrheit für die Verbindung, ein Ereignis, das sich bei Änderung in jeden Teil der Oberfläche verzweigt, und ein Banner, das direkt aus diesem Zustand liest. Es gibt keinen Weg, auf dem die Verbindung weg ist und die Oberfläche aktiv aussieht, weil beide aus derselben Tatsache lesen.

Die Lüge der verlorenen Aufnahme

Die zweite große Ehrlichkeits-Korrektur war die Aufnahme-Wiederherstellung. Echtzeit-Transkription braucht eine lebende Verbindung. In der v1 konnte, wenn diese Verbindung mitten in einer Sitzung stotterte — ein WLAN-Aussetzer, ein Tunnel, ein VPN-Reconnect — das Audio während der Lücke einfach weg sein. Das Transkript hatte ein Loch, und nichts sagte es dir.

Die v2 änderte den Vertrag: Audio wird während einer Verbindungslücke lokal gesichert und danach abgeglichen. Wenn die Verbindung abbricht, hält GeekBye das Audio sicher auf deinem Rechner; wenn sie zurückkommt, wird dieses gepufferte Audio gesendet und an der richtigen Stelle ins Transkript eingenäht. Dreißig schlechte Netzsekunden kosten dich keine dreißig Meeting-Sekunden mehr. Das ist das Fundament, auf dem die späteren Zuverlässigkeits-Releases direkt aufbauten — die Reconnect-und-Puffer-Mechanik in warum dein KI-Notiztool bei schlechtem WLAN stehen bleibt ist dieselbe Idee, gehärtet.

Die Lüge des Popup-Sturms

Es gibt eine subtilere Unehrlichkeit darin, wie Apps Probleme melden: Sie übermelden. Ein einziger wackliger Netzmoment kann denselben Fehler fünfmal auslösen, und plötzlich hast du einen Stapel identischer roter Toasts, der die eine Nachricht begräbt, die zählt. Das ist auch nicht ehrlich — es ist Rauschen, das sich als Information ausgibt.

Also fügte die v2 kategoriebasiertes Toast-Drosseln und Fehler-Routing hinzu. Fehler werden danach gruppiert, was sie wirklich sind, und jede Kategorie wird in der Frequenz begrenzt, damit ein einzelnes zugrunde liegendes Problem eine klare Nachricht erzeugt, kein Trommelfeuer. Ein Rate-Limit-Problem wird zu einer Rate-Limit-Nachricht geleitet; ein Verbindungsproblem zu einer Verbindungsnachricht. Die App sagt dir was wahr ist, einmal — dieselbe Disziplin, die später verhinderte, dass ein 429 sich als Logout ausgab in dem Tag, an dem unsere App sich selbst DDoS-te.

Die Zahl 206 ist der Punkt

Ehrliche Zustände, Reconnect-Banner, Aufnahme-Wiederherstellung, Toast-Routing — das sind vier Ideen. Das Release waren 206 Commits. Wo blieb der Rest?

In dem unglamourösen langen Schwanz, den „niemals einen falschen Zustand zeigen" tatsächlich verlangt. Jede Stelle, an der die alte Oberfläche mit der Realität aus dem Takt geraten konnte, musste gefunden und neu verdrahtet werden, damit sie aus der Wahrheit liest statt aus einer veralteten Kopie. Jeder Reconnect-Pfad musste dazu gebracht werden, den geteilten Zustand zu aktualisieren, statt lokal zu raten. Dutzende kleiner Zuverlässigkeits-Korrekturen quer durch Aufnahme, Transkription und Uploads — jede schloss eine bestimmte Lücke, in der die App richtig aussehen konnte, während sie falsch lag.

Das ist, was eine echte „Version 2" kostet, wenn das Ziel Vertrauen statt Features ist. Es gibt keinen einzelnen Schlagzeilen-Commit. Es gibt 206 kleine, und das Release fühlt sich nur deshalb wie eine einzige Sache an — Ruhe — weil alle 206 in dieselbe Richtung ziehen.

Das Release wäre fast nicht ausgeliefert worden

Hier ist die Kriegsgeschichte, und sie ist gut, denn es geht darum, wie unsere eigene App uns anlog.

Wenn du ein Release schneidest, stempelt ein Versions-Bump-Skript die neue Nummer quer durchs Projekt. Bei der v2.0.0 aktualisierte es die Version der App — aber die package-lock.json, npms exaktes Abhängigkeits-Register, blieb auf die alte Version 1.9.0 zeigen. Lokal war alles in Ordnung; niemand installiert Abhängigkeiten neu, nur um zu bauen. Aber die CI läuft mit npm ci, und die ganze Aufgabe von npm ci ist es, sich zu weigern fortzufahren, wenn das Lockfile mit dem Manifest uneins ist. Das ist ein Strenge-Feature — und es tat genau das, was es sollte, indem es den Build des größten Releases scheitern ließ, das wir je geschnitten hatten.

Dann tauchte ein zweites, hinterhältigeres darunter auf. Ein neueres npm hatte eine optionale transitive Abhängigkeit weggeschnitten — das Paket encoding, das node-fetch mitzieht — aus dem Lockfile als unnötig. Nur dass die saubere Installation unserer CI es doch brauchte, also brach die Installation auf eine Weise, die nichts mit unserem Code und alles mit dem subtil falschen Register zu tun hatte.

Beide waren Ein-Zeilen-Korrekturen: das Lockfile auf die echte Version resynchronisieren, den weggeschnittenen Eintrag wiederherstellen. Beide sind auch perfekte, demütigende Beispiele für genau das, worum es bei der v2 ging — ein Zustand, der behauptete, wahr zu sein, und es nicht war. Das Lockfile soll das ehrliche Register davon sein, wovon die App abhängt. Als es von der Realität abdriftete, tat der Build genau das, was unsere App jetzt für Nutzer tut: Er weigerte sich vorzugeben, alles sei in Ordnung. Ein Zuverlässigkeits-Release auszuliefern erweist sich als Zuverlässigkeitsproblem bis auf den Grund.

Drei Dinge, die uns die v2 lehrte

  1. Die gefährlichen Ausfälle sind die stillen. Ein Absturz kündigt sich selbst an. Ein falsches „verbunden", ein Phantom-Upload-Erfolg, ein Transkript mit einem unsichtbaren Loch — die kosten dich Vertrauen gerade deshalb, weil nichts falsch aussieht. Jage die stillen Lügen.
  2. Ehrlichkeit ist eine Architektur, keine Nachricht. Du kannst „sag die Wahrheit" nicht als Banner an eine Oberfläche schrauben. Das Banner muss aus derselben einzigen Quelle der Wahrheit lesen wie alles andere, sonst wird es zu einer weiteren Sache, die falsch sein kann. Eine Tatsache, verzweigt — niemals zwei Kopien, die sich widersprechen können.
  3. Eine Version 2, die die Zahl wert ist, ist größtenteils unsichtbar. Wenn deine v2 eine Feature-Liste ist, ist sie eine v1.5 mit Marketing. Eine echte v2 sind 206 Commits, auf die niemand einzeln zeigen kann, die sich zu einem Produkt summieren, das dich schlicht nicht mehr anlügt.

Die v2.0.0 von GeekBye ist das Fundament, auf dem jedes Release seither aufgebaut hat. Für das, was dieses Fundament trägt, siehe warum dein KI-Notiztool bei schlechtem WLAN stehen bleibt, den Tag, an dem unsere App sich selbst DDoS-te (v2.0.1) und Live-Transkription, wenn die Firewall WebSockets blockiert (v2.0.8). Für die Ruhe, in deren Dienst alles stand, was neu ist in GeekBye v2.