Steven
Steven6 Min. Lesezeit

Ruhige Software: einen flackernden Schalter beseitigen und dem Chat beibringen, in welchem Modus er ist

Zwei kleine GeekBye-Releases, keine Vorzeigefunktionen — nur ein Einstellungs-Schalter, der aufgehört hat zu flackern, und ein Chat-Assistent, der dir endlich sagt, ob er im Meeting-Modus oder im Coding-Modus geantwortet hat. Genau das kostet "ruhige Software" wirklich, ein Detail nach dem anderen.

Produkt
Design
Technik
GeekBye-Releases
Ruhige Software: einen flackernden Schalter beseitigen und dem Chat beibringen, in welchem Modus er ist

Nicht jedes Release ist eine Kriegsgeschichte. Manche sind nur eine Liste kleiner, fast unsichtbarer Dinge, die still und leise falsch waren — die Art von Dingen, die nichts zum Absturz bringen, aber eine App ein bisschen wenig vertrauenswürdig, ein bisschen nervös, ein bisschen nicht-deine wirken lassen. GeekBye v2.0.3 und v2.0.5 waren zwei davon. Keine neuen Funktionen. Nur Ruhe.

"Ruhige Software" klingt nach einer Stimmung. In Wirklichkeit ist es ein Stapel konkreter Entscheidungen. Hier sind drei davon.

Ein Schalter, der sich nicht entscheiden konnte

Es gab einen Einstellungs-Schalter — den für die Audio-Wiederherstellung —, der beim Anklicken flackerte. Man tippte ihn an, und für den Bruchteil einer Sekunde zeigte er an, sprang dann zurück auf aus, und pendelte sich schließlich ein. Ein winziges visuelles Stottern, aber das Auge fängt es ein, und es liest sich als die App ist sich nicht sicher, was sie tut.

Die Ursache ist ein klassischer UI-Wettlauf namens optimistische Aktualisierung. Wenn man einen Schalter klickt, hat die App zwei Möglichkeiten: warten, bis die Einstellung tatsächlich gespeichert ist, und dann den Schalter aktualisieren (korrekt, aber es fühlt sich träge an), oder den Schalter sofort umlegen und im Hintergrund speichern (fühlt sich sofortig an). GeekBye tat Letzteres — sofort umlegen — las aber auch den gespeicherten Wert erneut, wenn er zurückkam. Die Abfolge war also: du klickst, der Schalter geht optimistisch an, der echte gespeicherte Wert kommt einen Moment später, und für ein Frame widersprachen sich die beiden, und der Schalter sprang sichtbar.

Die Lösung besteht darin, dass optimistischer und bestätigter Wert sauber übereinstimmen — der Schalter legt sich auf den von dir gewählten Zustand fest und hört auf, an sich zu zweifeln, wenn das Speichern bestätigt wird. Daneben machte v2.0.3 einen unspektakulären Textdurchgang: die Beschreibung der Audio-Wiederherstellung wurde gekürzt, um sich an ihre Nachbarzeilen anzugleichen, und die Formulierung der Einstellungen wurde menschlicher gemacht. Nichts davon ist eine Funktion. Alles davon ist der Unterschied zwischen einem Einstellungsfenster, das sich zusammengebaut anfühlt, und einem, das sich liebevoll ausgearbeitet anfühlt.

Eine Tour, die nicht gehen wollte

Touren für neue Nutzer sind genau einmal nützlich. Das Problem ist die Einmaligkeit: Hat man sie einmal gesehen, wird ein Onboarding-Overlay, das man nicht wegklicken kann, zu Ballast, der signalisiert diese App hält dich immer noch für neu. v2.0.3 behob beide Enden — die Produkttour lässt sich jetzt ausblenden, und wenn man sie wirklich zurückhaben will, gibt es eine Schaltfläche Tour wiederholen. Zeig sie, wenn sie hilft, geh aus dem Weg, wenn nicht, und lass den Nutzer sie zu seinen Bedingungen herbeirufen. Zu respektieren, dass der Nutzer nicht mehr neu ist, ist seine eigene kleine Form von Ruhe.

Der Assistent, der nicht sagte, wie er dachte

Das ist der, der wirklich zählte, und er hängt mit einem tieferen Problem zusammen, dem wir nachgingen.

Der Assistent von GeekBye antwortet je nach Kontext unterschiedlich. In einem Meeting sollte "was hältst du davon?" eine gesprächige, meeting-bewusste Antwort bekommen. In einer Coding-Sitzung sollten dieselben Worte eine technische bekommen. Also schickt das Backend die Frage durch den richtigen Rahmen — nenne es Meeting-Modus oder Coding-Modus — und diese Einordnung verändert die Antwort, die du bekommst, wirklich.

Der Haken: Die App sagte dir nie, welcher Modus geantwortet hatte. Wenn der Assistent dir also eine code-lastige Antwort auf eine gesprächige Frage gab — oder eine Code-Frage beantwortete, als würdest du plaudern —, sah es so aus, als läge die KI einfach falsch. Sie lag nicht falsch; sie war im anderen Modus, und du hattest keine Möglichkeit, das zu sehen. Ein verborgener Zustand ließ korrektes Verhalten kaputt aussehen. (Die Modus-Logik selbst ist ein größeres Stück Arbeit — der Orchestrator, der entscheidet, wie nicht-code-bezogene Fragen während einer Coding-Sitzung zu beantworten sind — aber all das nützt dir nichts, wenn du die getroffene Entscheidung nicht sehen kannst.)

v2.0.5 fügte dem Chat einen schreibgeschützten Modus-Chip hinzu: eine kleine Kennzeichnung, die zeigt, ob der Assistent im Meeting-Modus oder im Coding-Modus geantwortet hat. Schreibgeschützt ist der ganze Punkt — es ist kein Regler, den du einstellst, sondern ein Fenster in eine Entscheidung, die das System bereits getroffen hat. Du rätst nicht mehr, warum sich eine Antwort falsch anfühlt; du kannst den Rahmen sehen, aus dem sie kam.

Das Detail, das den Chip ehrlich macht

Hier ist die technische Entscheidung, die es wert ist, weitergegeben zu werden, denn sie ist von der Sorte, die eine angeschraubte Anzeige von einer vertrauenswürdigen unterscheidet.

Die Modus-Information kommt vom Backend als Teil der gestreamten Antwort — ein kleines mode-Frame im Strom der Server-Sent Events. Aber ein älterer Client, der vor dieser Funktion existierte, wüsste nicht, was ein mode-Frame ist; bestenfalls ignoriert er es, schlimmstenfalls rendert er etwas Verstümmeltes. Also kündigt der Client seine Fähigkeit an: Er sendet einen Request-Header, der sagt ich kann einen Modus-Chip anzeigen, und das Backend gibt das mode-Frame nur an Clients aus, die ihn gesendet haben. Alte Clients erhalten nie ein Signal, mit dem sie nichts anfangen können; neue erhalten genau das Frame, um das sie gebeten haben.

Es ist ein Handshake aus einem einzigen Header, und es ist der Unterschied zwischen "wir haben eine Funktion hinzugefügt" und "wir haben eine Funktion hinzugefügt, ohne jemandem etwas kaputtzumachen, der noch nicht aktualisiert hat." Derselbe Review-Durchgang zurrte auch das übrige Verhalten fest: Der Chip löscht sich beim Zurücksetzen und wenn sich der Gesprächskontext ändert (ein veraltetes Modus-Label ist seine eigene kleine Lüge), und er erscheint nur in der Chat-Ansicht, wo er hingehört.

Was uns zwei "funktionslose" Releases gelehrt haben

  1. Nervosität ist ein Vertrauenssignal. Ein flackernder Schalter, ein springender Umschalter, ein Label, das ein Frame zu lange verweilt — keins davon ist ein Bug im Sinne eines Absturzes, aber jedes flüstert diese App hat sich nicht ganz im Griff. Ruhe ist die Abwesenheit dieses Flüsterns, und man verdient sie sich eine Race Condition nach der anderen.
  2. Ein verborgener Modus lässt korrektes Verhalten wie einen Bug aussehen. Der Assistent tat das Richtige und bekam die Schuld dafür, einzig weil der Nutzer den Rahmen nicht sehen konnte. Wenn dein System eine unsichtbare Entscheidung trifft, die die Ausgabe verändert, zeig die Entscheidung — ein schreibgeschützter Chip ist oft die ganze Lösung.
  3. Neue Funktionen sollten für Clients, die sie nicht nutzen können, unsichtbar sein. Der Handshake per Fähigkeits-Header sorgt dafür, dass das Modus-Signal nur die Clients erreicht, die es rendern können. Abwärtskompatibilität ist keine später angeschraubte Versionsprüfung; sie ist ein Client, der sagt, was er versteht, und ein Server, der die Antwort respektiert.

Das sind die Releases, über die niemand Changelog-Schlagzeilen schreibt, und sie sind ein großer Teil davon, warum sich GeekBye v2 so anfühlt, wie es sich anfühlt. Zum Release, auf dem diese Ruhe aufgebaut wurde, siehe was eine Version 2 wirklich kostet (v2.0.0). Zur Zuverlässigkeitsarbeit daneben, der Tag, an dem sich unsere App selbst DDoSte (v2.0.1) und warum dein KI-Notizen-Tool mitten im Meeting aufhört aufzunehmen (v2.0.9).

Ähnliche Artikel

Eine CSS-Variable, fünf Review-Runden und eine Swift-Toolchain, die log
Steven
Steven7 Min. Lesezeit

Eine CSS-Variable, fünf Review-Runden und eine Swift-Toolchain, die log

GeekBye v2.0.7 machte das gesamte Overlay verstellbar durchscheinend — was nach einer einzeiligen CSS-Änderung klingt und definitiv keine war. Die eigentliche Geschichte ist, was das Code-Review aufdeckte: zwei Flächen, die sich weigerten zu verblassen, eine Aufnahmeleiste, die bei gleicher Deckkraft falsch aussah, und ein kompiliertes Binary, das um 672 Bytes hin und her sprang, weil unsere eigene Dokumentation einem Reviewer die falsche Swift-Version nannte.

Engineering
Design
Build
Was eine Version 2 wirklich kostet: 206 Commits ehrlicher Zustände
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
Deine Mac-App erteilt Mikrofonzugriff — und vergisst ihn bei jedem Start
Steven
Steven6 Min. Lesezeit

Deine Mac-App erteilt Mikrofonzugriff — und vergisst ihn bei jedem Start

GeekBye hat um Mikrofonzugriff gebeten, du hast ihn erteilt, und es hat funktioniert. Beim nächsten Start: weg. Und die App tauchte in den Systemeinstellungen → Mikrofon nie überhaupt auf. Schuld war eine Sicherheitsfunktion von macOS, die die App still aus einem Pfad ausführte, der sich in Luft auflöst — hier ist die Diagnose und der Ein-Klick-Fix.

macOS
Berechtigungen
Engineering