
Wat een versie 2 echt kost: 206 commits vol eerlijke toestanden
GeekBye v2 was geen feature-release. Het waren 206 commits met één doel voor ogen: de app mag nooit liegen over zijn eigen toestand. Dit is wat dat kost — inclusief de eenregelige lockfile-fout die ons bijna belette om er ook maar iets van uit te brengen.
De meeste "versie 2"-releases zijn een stapel nieuwe features met een groter getal erop. GeekBye v2 was het tegenovergestelde. Het bracht bijna geen nieuwe zichtbare mogelijkheid voor de gebruiker. De 206 commits waren gericht op één enkel, weinig glamoureus idee:
De app mag je nooit een toestand tonen die niet waar is.
Dat klinkt vanzelfsprekend totdat je telt op hoeveel manieren een desktop-app stilletjes liegt. Hij toont een vinkje bij een upload die nog onderweg is. Hij zegt "verbonden" over een socket die een minuut geleden is gestorven. Hij blijft stil terwijl je transcript op de grond wordt gegooid. Geen van deze zijn crashes. Ze zijn erger dan crashes, omdat de app er prima uitziet terwijl hij fout zit — en je komt er pas later achter, wanneer de opname die je nodig had er niet is.
v2 was de release waarin we op jacht gingen naar elk van die kleine leugens.
De leugen die we het meest haatten: de upload die "lukte"
GeekBye kan je opnames back-uppen naar Google Drive. In v1 werd de verbinding met Drive behandeld als een achtergronddetail — als het werkte, mooi; als het niet werkte, was de fout grotendeels onzichtbaar. De app bleef er verbonden uitzien. Je nam aan dat je opnames veilig waren. Soms waren ze dat niet.
v2 herbouwde dit rond eerlijke verbindingstoestanden. Drive is nu altijd in één van een paar expliciete, waarheidsgetrouwe toestanden — verbonden, herverbinden, verbroken — en de app zendt elke wijziging van die toestand naar de hele interface op het moment dat het gebeurt. Wanneer de verbinding weg is, vertelt een globale herverbindingsbanner het je, overal, ronduit. De app doet niet langer alsof een upload is gelukt terwijl dat niet zo is. Als je back-up nu niet kan plaatsvinden, weet je dat nu — niet volgende week wanneer je het bestand gaat zoeken.
Onderhuids is dit een kleine architectuur, geen slogan: één bron van waarheid voor de verbinding, een event dat uitwaaiert naar elk deel van de UI wanneer het verandert, en een banner die rechtstreeks uit die toestand leest. Er is geen pad waarin de verbinding weg is en de UI er goed uitziet, want ze lezen uit hetzelfde feit.
De leugen van de verloren opname
De tweede grote eerlijkheidsfix was opnameherstel. Real-time transcriptie heeft een live verbinding nodig. In v1, als die verbinding halverwege een sessie haperde — een wifi-blip, een tunnel, een VPN-herverbinding — kon de audio tijdens het gat simpelweg verdwenen zijn. Het transcript had een gat en niets vertelde het je.
v2 veranderde het contract: audio wordt lokaal bewaard tijdens een verbindingsgat en achteraf verzoend. Wanneer de link wegvalt, houdt GeekBye de audio veilig op je machine; wanneer hij terugkomt, wordt die gebufferde audio verzonden en op de juiste plek in het transcript geweven. Een slechte dertig seconden netwerk kost je niet langer dertig seconden meeting. Dit is het fundament waarop de latere betrouwbaarheidsreleases rechtstreeks bouwden — de herverbind-en-buffer-machinerie in waarom je AI-notulist stopt bij slechte wifi is hetzelfde idee, geharde.
De leugen van de pop-upstorm
Er zit een subtielere oneerlijkheid in hoe apps problemen rapporteren: ze overrapporteren ze. Eén haperend netwerkmoment kan dezelfde fout vijf keer afvuren, en opeens heb je een stapel identieke rode toasts die het ene bericht dat ertoe doet bedelven. Dat is ook niet eerlijk — het is ruis die zich voordoet als informatie.
Dus voegde v2 categoriegesleutelde toast-throttling en foutroutering toe. Fouten worden gegroepeerd op basis van wat ze werkelijk zijn, en elke categorie wordt rate-limited zodat één onderliggend probleem één helder bericht oplevert, geen spervuur. Een rate-limit-probleem leidt naar een rate-limit-bericht; een verbindingsprobleem leidt naar een verbindingsbericht. De app vertelt je wat waar is, één keer — dezelfde discipline die later een 429 ervan weerhield zich voor te doen als een logout in de dag dat onze app zichzelf DDoSte.
Het getal 206 is het punt
Eerlijke toestanden, herverbindingsbanner, opnameherstel, toast-routering — dat zijn vier ideeën. De release was 206 commits. Waar ging de rest heen?
Naar de weinig glamoureuze lange staart die "toon nooit een valse toestand" daadwerkelijk vereist. Elke plek waar de oude UI uit de pas kon lopen met de werkelijkheid moest gevonden en herbedraad worden om uit de waarheid te lezen in plaats van uit een verouderde kopie. Elk herverbindingspad moest worden gemaakt om de gedeelde toestand bij te werken in plaats van lokaal te gokken. Tientallen kleine betrouwbaarheidsfixes over opname, transcriptie en uploads — elk ervan sloot een specifiek gat waar de app er goed kon uitzien terwijl hij fout zat.
Dit is wat een echte "versie 2" kost wanneer het doel vertrouwen is in plaats van features. Er is geen enkele kop-commit. Er zijn er 206 kleine, en de release voelt alleen aan als één ding — kalm — omdat alle 206 dezelfde kant op trekken.
De release werd bijna niet uitgebracht
Hier komt het oorlogsverhaal, en het is een goede, want het gaat over onze eigen app die tegen ons liegt.
Wanneer je een release maakt, stempelt een versiebump-script het nieuwe getal door het hele project. Bij v2.0.0 werkte het de versie van de app bij — maar de package-lock.json, npm's exacte dependency-grootboek, bleef verwijzen naar de oude versie, 1.9.0. Lokaal was alles in orde; niemand herinstalleert dependencies alleen om te builden. Maar CI draait npm ci, en de hele taak van npm ci is om te weigeren door te gaan als de lockfile niet overeenkomt met het manifest. Het is een strengheidsfeature — en het deed precies wat het moest doen, door de build te laten falen voor de grootste release die we ooit hadden gemaakt.
Toen dook er een tweede, geniepiger probleem eronder op. Een nieuwere npm had een optionele transitieve dependency gesnoeid — het encoding-pakket dat node-fetch binnenhaalt — als onnodig uit de lockfile. Behalve dat de schone install van onze CI het wél nodig had, dus de install brak op een manier die niets met onze code te maken had en alles met het grootboek dat subtiel fout was.
Beide waren eenregelige fixes: de lockfile resynchroniseren naar de echte versie, de gesnoeide entry herstellen. Beide zijn ook perfecte, nederig makende voorbeelden van precies datgene waar v2 over ging — een toestand die beweerde waar te zijn en dat niet was. De lockfile hoort het eerlijke verslag te zijn van waar de app van afhangt. Toen hij afdreef van de werkelijkheid, deed de build precies wat onze app nu doet voor gebruikers: hij weigerde te doen alsof alles in orde was. Een betrouwbaarheidsrelease uitbrengen blijkt helemaal tot aan de bodem een betrouwbaarheidsprobleem te zijn.
Drie dingen die v2 ons leerde
- De gevaarlijke fouten zijn de stille. Een crash kondigt zichzelf aan. Een vals "verbonden," een spookachtige geslaagde upload, een transcript met een onzichtbaar gat — die kosten je vertrouwen juist omdat er niets fout lijkt. Jaag op de stille leugens.
- Eerlijkheid is een architectuur, geen bericht. Je kunt "vertel de waarheid" niet als een banner op een UI schroeven. De banner moet uit dezelfde ene bron van waarheid lezen als al het andere, anders wordt het nog een ding dat fout kan zijn. Eén feit, uitgewaaierd — nooit twee kopieën die het oneens kunnen zijn.
- Een versie 2 die het getal waard is, is grotendeels onzichtbaar. Als je v2 een featurelijst is, is het een v1.5 met marketing. Een echte v2 is 206 commits waar niemand afzonderlijk naar kan wijzen, die samen optellen tot een product dat simpelweg stopt met tegen je liegen.
GeekBye v2.0.0 is het fundament waarop elke release sindsdien heeft gebouwd. Voor wat dat fundament draagt, zie waarom je AI-notulist stopt bij slechte wifi, de dag dat onze app zichzelf DDoSte (v2.0.1), en live transcriptie wanneer de firewall WebSockets blokkeert (v2.0.8). Voor de rust waar het allemaal in dienst van stond, wat is er nieuw in GeekBye v2.