
Ce presupune cu adevărat o Versiune 2: 206 commit-uri de stări oneste
GeekBye v2 nu a fost o lansare de funcții. Au fost 206 commit-uri îndreptate spre o singură idee: aplicația nu ar trebui să mintă niciodată despre propria ei stare. Iată cât costă asta — inclusiv greșeala de o linie din lockfile care era să ne împiedice să lansăm ceva din toate acestea.
Majoritatea lansărilor „versiunea 2" sunt un morman de funcții noi cu un număr mai mare pe ele. GeekBye v2 a fost exact opusul. Nu a livrat aproape nicio capabilitate nouă vizibilă pentru utilizator. Cele 206 commit-uri ale sale au fost îndreptate spre o singură idee, deloc spectaculoasă:
Aplicația nu ar trebui să-ți arate niciodată o stare care nu e adevărată.
Sună evident până începi să numeri în câte feluri o aplicație desktop minte pe tăcute. Arată o bifă pe o încărcare care e încă în zbor. Spune „conectat" peste un socket care a murit acum un minut. Rămâne tăcută în timp ce transcrierea ta e aruncată pe jos. Niciuna dintre acestea nu e un crash. Sunt mai rele decât un crash, pentru că aplicația pare în regulă în timp ce greșește — și afli abia mai târziu, când înregistrarea de care aveai nevoie nu e acolo.
v2 a fost lansarea în care am pornit la vânătoare după fiecare dintre aceste mici minciuni.
Minciuna pe care am urât-o cel mai mult: încărcarea care „a mers"
GeekBye poate să-ți facă backup înregistrărilor în Google Drive. În v1, conexiunea la Drive era tratată ca un detaliu de fundal — dacă mergea, grozav; dacă nu, eșecul era în mare parte invizibil. Aplicația continua să pară conectată. Presupuneai că înregistrările tale erau în siguranță. Uneori nu erau.
v2 a reconstruit asta în jurul unor stări oneste ale conexiunii. Drive se află acum mereu într-una dintre câteva stări explicite și adevărate — conectat, se reconectează, deconectat — iar aplicația difuzează fiecare schimbare a acelei stări către întreaga interfață în clipa în care se întâmplă. Când conexiunea e picată, un banner global de reconectare îți spune, peste tot, clar. Aplicația nu mai pretinde că o încărcare a reușit când nu a reușit. Dacă backupul tău nu poate avea loc chiar acum, afli chiar acum — nu săptămâna viitoare, când te apuci să cauți fișierul.
Dedesubt, asta e o arhitectură mică, nu un slogan: o singură sursă de adevăr pentru conexiune, un eveniment care se răspândește către fiecare parte a interfeței când se schimbă, și un banner care citește direct din acea stare. Nu există niciun traseu în care conexiunea e picată și interfața arată că e sus, pentru că amândouă citesc din același fapt.
Minciuna înregistrării pierdute
Al doilea mare fix de onestitate a fost recuperarea înregistrărilor. Transcrierea în timp real are nevoie de o conexiune vie. În v1, dacă acea conexiune se împiedica la mijloc de sesiune — un blip de Wi-Fi, un tunel, o reconectare de VPN — audio-ul din timpul întreruperii putea pur și simplu să dispară. Transcrierea avea o gaură în ea, și nimic nu-ți spunea.
v2 a schimbat contractul: audio-ul e păstrat local în timpul unei întreruperi de conexiune și reconciliat după aceea. Când legătura pică, GeekBye păstrează audio-ul în siguranță pe mașina ta; când revine, acel audio tamponat e trimis și cusut în transcriere la locul potrivit. Treizeci de secunde proaste de rețea nu te mai costă treizeci de secunde de ședință. Aceasta e temelia pe care lansările ulterioare de fiabilitate au construit direct — mașinăria de reconectare-și-tamponare din de ce notetaker-ul tău AI se oprește pe Wi-Fi prost e aceeași idee, întărită.
Minciuna furtunii de popup-uri
Există o necinste mai subtilă în felul în care aplicațiile raportează problemele: le supra-raportează. Un singur moment instabil de rețea poate declanșa aceeași eroare de cinci ori, și dintr-odată ai un teanc de toast-uri roșii identice care îngroapă singurul mesaj care contează. Nici asta nu e onest — e zgomot care se dă drept informație.
Așa că v2 a adăugat throttling de toast-uri pe categorii și direcționarea erorilor. Erorile sunt grupate după ceea ce sunt cu adevărat, iar fiecare categorie e rate-limitată, așa că o singură problemă de bază produce un mesaj clar, nu un baraj. O problemă de rate-limit se direcționează către un mesaj de rate-limit; o problemă de conexiune se direcționează către un mesaj de conexiune. Aplicația îți spune ce e adevărat, o singură dată — aceeași disciplină care mai târziu a împiedicat un 429 să se dea drept logout în ziua în care aplicația noastră și-a făcut singură DDoS.
Numărul 206 e chiar ideea
Stări oneste, banner de reconectare, recuperarea înregistrărilor, direcționarea toast-urilor — astea sunt patru idei. Lansarea a avut 206 commit-uri. Unde s-a dus restul?
În coada lungă și deloc spectaculoasă pe care „nu arăta niciodată o stare falsă" chiar o cere. Fiecare loc în care vechea interfață se putea desincroniza de realitate a trebuit găsit și recablat să citească din adevăr în loc dintr-o copie învechită. Fiecare traseu de reconectare a trebuit făcut să actualizeze starea comună în loc să ghicească local. Zeci de mici fixuri de fiabilitate în înregistrare, transcriere și încărcări — fiecare închizând o breșă specifică unde aplicația putea să pară corectă în timp ce greșea.
Asta costă o „versiune 2" reală când scopul e încrederea în loc de funcții. Nu există un singur commit-titlu. Sunt 206 mici, iar lansarea pare un singur lucru — calm — doar pentru că toate 206 trag în aceeași direcție.
Lansarea era să nu se întâmple
Iată povestea de război, și e una bună, pentru că e despre cum propria noastră aplicație ne-a mințit pe noi.
Când tai o lansare, un script de bump de versiune ștampilează noul număr peste tot proiectul. La v2.0.0 a actualizat versiunea aplicației — dar package-lock.json, registrul exact al dependențelor npm, a fost lăsat să pointeze la versiunea veche, 1.9.0. Local, totul era în regulă; nimeni nu reinstalează dependențele doar ca să facă build. Dar CI rulează npm ci, iar toată treaba lui npm ci e să refuze să continue dacă lockfile-ul e în dezacord cu manifestul. E o funcție de strictețe — și a făcut exact ce trebuia, eșuând build-ul pentru cea mai mare lansare pe care o tăiaserăm vreodată.
Apoi a apărut dedesubt o a doua, mai vicleană. Un npm mai nou elidase o dependență tranzitivă opțională — pachetul encoding pe care node-fetch îl trage după el — din lockfile ca fiind inutilă. Doar că instalarea curată din C-ul nostru chiar avea nevoie de ea, așa că instalarea s-a stricat într-un fel care nu avea nimic de-a face cu codul nostru și totul de-a face cu registrul fiind subtil greșit.
Ambele au fost fixuri de o linie: resincronizează lockfile-ul la versiunea reală, restaurează intrarea elidată. Ambele sunt și exemple perfecte, umilitoare, exact al lucrului despre care era vorba în v2 — o stare care pretindea că e adevărată și nu era. Lockfile-ul e menit să fie înregistrarea onestă a ceea ce depinde aplicația. Când s-a abătut de la realitate, build-ul a făcut exact ce face acum aplicația noastră pentru utilizatori: a refuzat să pretindă că totul era în regulă. Se dovedește că a livra o lansare de fiabilitate e o problemă de fiabilitate până în adânc.
Trei lucruri pe care ne-a învățat v2
- Eșecurile periculoase sunt cele tăcute. Un crash se anunță singur. Un fals „conectat", o încărcare-fantomă reușită, o transcriere cu o gaură invizibilă — acelea te costă încredere tocmai pentru că nimic nu pare în neregulă. Vânează minciunile tăcute.
- Onestitatea e o arhitectură, nu un mesaj. Nu poți lipi „spune adevărul" pe o interfață ca un banner. Bannerul trebuie să citească din aceeași sursă unică de adevăr ca tot restul, altfel devine încă un lucru care poate fi greșit. Un fapt, răspândit — niciodată două copii care pot fi în dezacord.
- O versiune 2 care merită numărul e în mare parte invizibilă. Dacă v2-ul tău e o listă de funcții, e un v1.5 cu marketing. Un v2 real e 206 commit-uri pe care nimeni nu le poate arăta individual, adunându-se într-un produs care pur și simplu încetează să te mai mintă.
GeekBye v2.0.0 e temelia pe care a construit fiecare lansare de atunci. Pentru ce cară acea temelie, vezi de ce notetaker-ul tău AI se oprește pe Wi-Fi prost, ziua în care aplicația noastră și-a făcut singură DDoS (v2.0.1) și transcriere live când firewall-ul blochează WebSocket-urile (v2.0.8). Pentru calmul în slujba căruia a fost totul, ce e nou în GeekBye v2.