Programowanie już nie chodzi o kod (Coding Isn't About Code Anymore)

2026-11-09 • Theo - t3.gg • AI zagraniczne •opinia •waga 3/5 •33 min czytania

Theo z t3.gg przekonuje, że inżynier staje się ogrodnikiem kodu — pielęgnuje środowisko, w którym pracują agenty AI. Konkrety z Twitcha i T3 Chat dla każdego, kto koduje z agentami.

Robocza publikacja redakcyjna na podstawie publicznego transkryptu YouTube. Źródło: YouTube.

O czym jest ten film

  1. Teza Theo: inżynierowie przestają być inżynierami w klasycznym sensie — nową rolą jest „ogrodnik”: utrzymywanie środowiska, w którym kod rośnie we właściwym kierunku.
  2. Ostrzeżenie: jeśli przez ostatni rok narzędzia AI nie zmieniły sposobu, w jaki piszesz kod, w ciągu roku–dwóch możesz stracić pracę.
  3. Wspomnienia z Twitcha (2017–2021): podział na zespoły produktowe (czat, panel twórcy, narzędzia moderacyjne) i platformowe (browser clients, GraphQL Edge, infrastruktura danych i wideo).
  4. Lekcja od Dereka: słaby pull request to sygnał, że dokumentacja lub przykłady w kodzie wprowadzają w błąd — naprawiaj przyczynę, nie objaw.
  5. Samodzielna praca po odejściu z Twitcha: narodziny T3 stack (Next.js, TypeScript, Prisma, tRPC) i świadomy podział czasu pół na pół między platformę i produkt.
  6. Anegdota o blobie JSON w GraphQL: jedna rozmowa z szefem zespołu platformowego rozwiązała problem, na którym utknął cały zespół produktowy.
  7. Ostatni wielki remont pisany ręcznie: migracja T3 Chat z autorskiego silnika synchronizacji na Convex — ponad 25 tysięcy linii w jednym PR.
  8. Kluczowe przeformułowanie: „slop Sonnet 4.5 blokował Opusa 5.5” — kod niskiej jakości hamuje także agentów piszących kolejne zmiany.
  9. Konkretne zabiegi „ogrodnicze”: kasowanie 250 tysięcy linii bezużytecznych testów, odpytywanie agentów o motywacje, automatyczna kontrola rozmiaru transferu danych w CI.
  10. Efekt zdrowego ogrodu: wzrost z 2–20 do 60–400+ scalonych PR-ów dziennie po uporządkowaniu bazy kodu.

10 najważniejszych takeaways — z kontekstem zastosowania

1.Z inżyniera zostaje ogrodnik — buduj środowisko, nie kod

Na czym polega: Theo mówi wprost: „nie jesteśmy już naprawdę inżynierami”. Zadanie nie polega na tym, by samemu „hodować” kod, lecz na przygotowaniu środowiska, w którym kod — dziś coraz częściej pisany przez agentów — rośnie we właściwym kierunku: z aktualną dokumentacją, dobrymi przykładami, monitoringiem i szybkim sprzężeniem zwrotnym.

Jak stosować: przesuń część uwagi z pisania funkcji na stan repozytorium. Oceniaj swoją pracę pytaniem: „czy następna osoba — albo agent — zrobi tu właściwą rzecz bez zbędnego oporu?”.

Na co uważać: „ogrodnik” nie oznacza biernego nadzorcy. Theo podkreśla, że nigdy nie czuł się bardziej jak ktoś, kto buduje platformę — to wciąż inżynieria, tylko piętro wyżej.

2.Każdy słaby pull request to sygnał, że platforma kuleje

Na czym polega: historia Dereka z Twitcha: zły PR zaowocował w pół godziny dwoma innymi — jednym czyszczącym mylący fragment dokumentacji, drugim przepisującym mylący kod w repozytorium. Złe zmiany zwykle nie wynikają z niedbałości autora, tylko z tego, że docs albo przykłady prowadzą na manowce.

Jak stosować: w review pytaj „co skłoniło cię do takiego rozwiązania?” i szukaj źródła pomyłki — akapitu w dokumentacji, złego wzorca w kodzie, brakującej abstrakcji. Napraw to u źródła.

Na co uważać: ignorowanie takich sygnałów oznacza, że poprzeczka sama opada, a jakość całego otoczenia eroduje bardzo szybko.

3.Jakość kodu to w dużej mierze problem organizacji i komunikacji

Na czym polega: dobrze zbudowana platforma sprawia, że przeciętny i wybitny inżynier scalają kod zbliżonej jakości — bo właściwa droga jest najłatwiejsza. W ten sposób Theo odpiera zarzut, że „JavaScriptowcom nie zależy na jakości”.

Jak stosować: gdy jakość spada, zanim zaczniesz od ludzi, zajrzyj do procesu: co w repozytorium lub dokumentacji czyni złą ścieżkę kuszącą?

Na co uważać: teza nie opiera się na zarządzaniu, morderczym code review, guardrails ani pokryciu testami — Theo wymienia je wprost jako rzeczy, o których nie mówił. Chodzi o współpracę platformy z produktem.

4.Wahadło: umiej wycofać się z produktu do platformy

Na czym polega: Theo krąży w karierze między budowaniem funkcji a poprawianiem podłoża. Gdy implementacja staje się trudniejsza, niż powinna, „odpuszcza” — idzie poprawić platformę, a wraca do funkcji, gdy grunt znów jest stabilny.

Jak stosować: traktuj opór jako sygnał. Jeśli walka z bazą kodu zjada więcej czasu niż sama funkcja, zrób przerwę i usuń źródło oporu. Nie traktuj pracy platformowej i produktowej jako osobnych ról — zacieraj granice.

Na co uważać: praca platformowa bywa niewidoczna dla użytkowników (Theo jako samotny deweloper scalał całą połowę PR-ów, których nikt nie widział, a które ułatwiały drugą połowę) — komunikuj w zespole jej wartość.

5.Tarć nie znoszą najlepiej agenci, tylko ludzie

Na czym polega: człowiek jakoś przeżyje pięciominutowy start serwera deweloperskiego czy piętnastominutową kontrolę typów. Agent w takim środowisku staje w miejscu — a przy długich TTL-ach dodatkowo spala tokeny, bo nie trafia w odczyty z pamięci podręcznej.

Jak stosować: zmierz czas startu dev servera, CI i ścieżki wydawniczej przez pryzmat agentów: ile razy na godzinę może obrócić się pętla weryfikacji zmiany? Tnij wszystko, co ją wydłuża.

Na co uważać: wolne CI ogranicza też równoległość — mniej równoległych zadań agentów oznacza mniejszą przepustowość całego zespołu.

6.Slop rośnie szybciej niż chwasty — pielęgnacja musi być ciągła

Na czym polega: masowo wygenerowany kod niskiej jakości (tzw. slop) namnaża się szybciej, niż ktokolwiek zdoła go posprzątać, jeśli nikt nie pilnuje ogrodu. Zły kod od jednego autora — lub modelu — blokuje wszystkich pozostałych.

Jak stosować: wcielaj zasadę „slop Sonnet 4.5 blokował Opusa 5.5”: patrz na każdy kiepski fragment jak na hamulec dla tych, którzy przyjdą po nim, agentów włącznie. Sprzątaj na bieżąco, nie kwartalnie.

Na co uważać: nawet po wielkim sprzątaniu nowe chwasty wyrastają — potrzebny jest stały nadzór, nie jednorazowa akcja.

7.Bezużyteczne testy kasuj bez sentymentów

Na czym polega: Theo usunął w jednym PR-ie około połowy testów jednostkowych w T3 Code — 250 tysięcy linii — bo testy, które niczego realnie nie chronią, mnożą kolejne bezsensowne przypadki brzegowe. Z jedenastu tysięcy przywrócił cztery i żadna regresja nie umknęła przez skasowane testy.

Jak stosować: audytuj testy pod kątem wartości: czy wykrycie tej konkretnej awarii jest realne i czy ktoś na tym polega? Kasuj te, które tylko udają czujność.

Na co uważać: po czystce obserwuj, czy słabe testy nie odrastają — i reaguj, dopóki problem jest mały.

8.Zły kod agenta? Zapytaj agenta, skąd się wziął

Na czym polega: gdy w T3 Code pojawiał się słaby test, autor zmiany wracał do wątku z agentem i pytał: „co skłoniło cię do dodania tego testu?”. Odpowiedź zwykle wskazywała źródło problemu — łodygę, z której wyrósł chwast — i dopiero ją usuwano.

Jak stosować: traktuj historię rozmowy z agentem jak log debugowania: pytaj o motywację, nie tylko o wynik. Napraw wskazówki, wzorce lub narzędzia, które wprowadziły model w błąd.

Na co uważać: pomagają też zmiany w wytycznych dla agentów w repo, ale same nie wystarczą — bez nadzoru chwasty wracają.

9.Tanie kontrole w CI to paliki, o które opiera się wzrost kodu

Na czym polega: zbudował „thread transfer impact tool” — kontrolę działającą w CI poniżej 45 sekund, która na każdym PR-ie wypisuje rozmiar przesyłanych danych i czerwi znaki przy regresjach. Dała to ludziom i agentom jasny sygnał, co podlega optymalizacji — i regresje, wcześniej umykające nawet w pozornie niegroźnych zmianach, zaczęły być łapane na wejściu.

Jak stosować: zamień metryki, na których ci zależy (rozmiar danych, czas odpowiedzi, zużycie pamięci), w automatyczny komentarz pod każdym PR-em. Agent pilnujący PR-ów sam zacznie je respektować.

Na co uważać: kontrola musi być tania i szybka — jeśli wydłuża CI, sama stanie się tarciem.

10.Efekt zdrowego ogrodu jest mierzalny

Na czym polega: w T3 Code liczba scalanych PR-ów wzrosła z 2–20 dziennie do 60 w słabsze dni i ponad 400 w dni pełne. To skutek sezonów niewidocznej pracy platformowej — takich jak migracja T3 Chat na Convex, po której reszta zespołu zaczęła się swobodnie poruszać po kodzie.

Jak stosować: traktuj przepustowość zmian jako miarę zdrowia repozytorium. Jeśli spada — szukaj chwastów, które blokują ludzi i agentów.

Na co uważać: sama liczba PR-ów nie jest celem; liczy się wartość, jaką te zmiany dowożą. Wysokie liczby bez kontroli jakości to również objaw slopu.

Redakcyjne tłumaczenie

Dla kogo jest ten materiał

Ostatnio znacznie więcej rozmawiam z inżynierami spoza mojej sanfranciskańskiej bańki — na konferencjach, na kursach, które wspieram, i przy różnych okazjach. Te rozmowy coraz częściej krążą wokół dwóch pytań: co właściwie znaczy dziś programować z AI i kim w ogóle jest jeszcze inżynier. Myślę o tym od dawna i od dawna chciałem nagrać o tym film. Będę z wami szczery: znam swoją sekcję komentarzy i wiem, ilu z was ten materiał wkurzy. Komentarze pod nim najpewniej w ogóle zignoruję, bo boję się zobaczyć, co tam będzie. Nie nagrywam go dla ludzi, którzy napiszą, że Theo to nieprawdziwy inżynier, tylko JavaScriptowiec przekonany o geniuszu AI — pewnie mądrzejszym od niego samego. Ten film jest dla deweloperów, którzy naprawdę chcą coś dowozić na produkcję, wykorzystać te technologie i zrozumieć, jaka rola zostanie im z czasem. Bo jeśli przez ostatni rok te narzędzia nie zmieniły sposobu, w jaki piszesz kod, to w ciągu najbliższego roku lub dwóch możesz stracić pracę. Właśnie w tym punkcie jesteśmy. Latałem wokół tej myśli przez lata i myliłem się. Wszystko się zmieniło — przede wszystkim to, jak pracujemy i czym jest nasza rola. Zmiana sięga głęboko, do samych fundamentów. Najprościej, jak umiem: nie jesteśmy już naprawdę inżynierami.

Skoro nie inżynierowie — to kto? Tech leadami? Product managerami? Projektantami? Wizjonerami? Będę bronił tezy, że naszą rolą jest teraz ogrodnik: najlepiej, co możemy zrobić, to utrzymywać zdrowy ogród. Wyjaśnienie tego zajmie chwilę. A jeśli się mylę w tej całej przemianie inżynierów w ogrodników, to znaczy, że jestem zwykłym influencerem. I niezbyt dobry z mnie influencer, skoro nie zrobię przerwy na dzisiejszego sponsora.

Przerwa na sponsoring

Może zauważyliście, że ostatnie mnóstwo rzeczy jest hakowanych. To nie przypadek: AI dobrze pisze kod, ale równie dobrze pisze exploity i znajduje słabości. Jest tylko haczyk — modele, których używamy na co dzień, nie potrafią same rzetelnie przeskanować naszego kodu i wskazać, co może być niebezpieczne, natomiast chętnie wygenerują kod niebezpieczny. Dlatego trzeba na bieżąco monitorować każdą nadchodzącą zmianę, rozumieć skalę potencjalnych szkód, które niesie, a najlepiej mieć jeszcze możliwość głębokiego skanowania starszego kodu w poszukiwaniu tego, co kiedyś umknęło. Kiedyś odkryta luka potrafiła czekać na wykorzystanie dwa lata i dłużej. Dziś exploity idą w świat, ledwie łata wyląduje w repozytorium. Najlepsza obrona: zadbaj o bezpieczeństwo, zanim kod wyjdzie na zewnątrz — bo im szybciej dostarczasz, tym łatwiej coś przepaści. Właśnie po to jest sponsor tego odcinka, CodeRabbit ze swoim nowym produktem do bezpieczeństwa: głębokie skany zaległości i kontrola każdego PR-a; czternaście dni za darmo w linku w opisie.

To, co kochamy w inżynierii

Ten materiał ma wiele warstw i zrobi się trochę chaotyczny — z góry przepraszam was i mojego montażystę. Widzę też na czacie obawy, że będzie to smutny film. Bardzo nie chcę, żeby taki był, więc zacznę trochę od końca: chcę, żebyście przestali bać się jednej rzeczy, a zachwycili drugą.

Nie wiem, jak wy, ale w inżynierii najbardziej kocham moment znalezienia właściwych klocków, złożenia ich właściwie i stworzenia czegoś naprawdę znaczącego. Uwielbiam ten „legowy” aspekt roboty. A ponad wszystko — to, że w odróżnieniu od klocków Lego, gdzie zawsze masz te same pojedyncze elementy, w inżynierii istnieją różne poziomy elementów składowych. Klockiem może być fizyczny krzem w chipie; można abstrahować wyżej i pisać asembler; wyżej — język typu C; dalej — runtime’y, pakiety i inne narzędzia. Da się pisać kod tak, by komponowały się pojedyncze linie, funkcje albo całe moduły. Swoboda wyboru miejsca cięcia i sposobu składania — to jest frajda. Dlatego kocham pisanie oprogramowania i samo budowanie.

Czego się bałem, to utraty tego wszystkiego. Wiem, że wielu ludzi obawia się, że uczucie majsterkowania, dopasowywania klocków, zniknie — bo gdy zaczynasz pracować z AI, sporo z tego, co kochaliśmy w programowaniu, po prostu przestaje istnieć. I to boli. Ale dobra wiadomość, którą mam nadzieję wyniesiecie z tego filmu, jest taka: po drugiej stronie tej przemiany problemy, które będziecie rozwiązywać, narzędzia, które będziecie składać, klocki, którymi będziecie budować — wszystko to jest zabawniejsze niż cokolwiek w mojej karierze. Serio: ostatnio chodzę spać o szóstej rano raz czy dwa razy w tygodniu, bo nie potrafię się oderwać od tego, co buduję. To niesamowicie wciągające i satysfakcjonujące. I nie robię tego ze strachu ani z obawy, że zostanę z tyłu. Robię to, bo kocham to teraz. Jeśli przyszliście tu przestraszeni — spróbujcie trochę uchylić umysł i skręcić ten lęk w dół, bo ja też go czułem. Mam szczęście, że moja kariera to nie tylko programowanie, więc przeszedłem przez to szybciej: nie sypał mi się świat, tylko jedno z hobby. A potem, po drugiej stronie, znalazłem w tym głębszą miłość.

Nie umiem opowiedzieć o tym inaczej niż bardzo osobiście. Najlepszy punkt startu to moje lata na Twitchu.

Lata na Twitchu: produkt kontra platforma

Pracowałem na Twitchu w latach 2017–2021 i przewinąłem przez kilka zespołów, ale chcę się skupić na wycinku z lat mniej więcej 2019–2021. Dlaczego? Najkrócej: w latach 2017–2018 szło mi nieźle, a między 2018 a 2019 omal mnie nie zwolniono, bo po prostu nie podobało mi się to, nad czym pracowałem. Gdy zespół, do którego przeszedłem, został rozwiązany, a dyrektor, który ściągnął mnie do firmy, odszedł, byłem po prostu nieszczęśliwy. Przetrwałem ten okres głównie dlatego, że nowy szef — trafiłem do niego w wewnętrznym przetasowaniu — mnie polubił. Widział, że jestem średni, ale motywowany. On był front-endowcem; ja — backendowcem od systemów, głównie od infrastruktury wideo i Elixira. Trafiłem do zespołu VOD-ów, miałem pisać w Go i byłem nędznie nastrojony. On zobaczył moją mękę, odciągnął mnie na bok i powiedział: spróbuj może tego nowego Reacta z TypeScripem, bo zaczynamy go u nas szerzej używać. Na początku jakoś mnie to nie porywało, ale coś zaczynało układać się w głowie. A potem przyszły hooki — gdy React dołożył wzorce funkcyjne — i ja, fan programowania funkcyjnego dzięki Elixirowi, złapałem bakcyla błyskawicznie. Model mentalny hooków pasował mi jak ulał.

I przeszedłem od „nie należę tu” (2017, połowa 2018) do „rozumiem, gdzie wszystko leży; wiem, jak te części się składają; mogę zmienić w systemie cokolwiek i przewidzieć, co się stanie”. Tego samego wyczucia nie dostawałem przy VOD-ach: wchodziłem do zespołu z gigantyczną bazą kodu w nieznanym mi języku, budowaną w sposób, do którego nie byłem przyzwyczajony.

W tym samym czasie Twitch odchodził od zaniedbanego Embera z Railsami w stronę Go, GraphQL oraz Reacta z TypeScripem. Dla mnie to była przepaść i okazja zarazem: byłem na miejscu, gdy to wszystko powstawało, i mogłem być adwokatem nowego podejścia. Bo w przeciwieństwie do weteranów przepisu, którzy mieli za sobą pięć lat Reacta i dekadę webu, ja przyszedłem do webu kilka tygodni wcześniej, z dziwacznym, niszowym doświadczeniem funkcyjnym — i byłem po prostu szczerze podekscytowany. Wzięli mnie pod skrzydła w zespole prowadzącym rdzeń produktu webowego.

Krótkie tło, jak Twitch dzielił zespoły. Większość to zespoły funkcjonalne: jest zespół czatu, który odpowiada za wszystko, co związane z czatem; jest zespół panelu twórcy, czyli widoku, w którym widzę wszystko, co dzieje się na moim streamie; jest też — mój osobisty faworyt — zespół narzędzi moderacyjnych, budujący platformę, dzięki której moderatorzy utrzymują czaty w bezpieczeństwie, w tym widok moderatora (mod view), o którym opowiadałem w innych filmach. Zabawnym trafem to właśnie moje trzy zespoły przy produkcie rdzeniowym. Każdy z nich posiadał w całości swoją powierzchnię: zespół narzędzi moderacyjnych miał backend, infrastrukturę, bazę danych, klienta, kod webowy — wszystko, z czym styka się użytkownik. Zespół czatu — protokoły, przepływ wiadomości w obie strony, backend, emotki i wbudowane w czat funkcje. Panel twórcy — analogicznie.

To jedna z dwóch głównych kategorii zespołów; druga to platformy. Bo choć zespoły produktowe posiadały swoje kawałki strony, backendu i bazy, ktoś musiał pilnować, żeby API nie padało i skalowało się tak, jak Twitch. Nie można wymagać od każdego zespołu, by każda jego decyzja skalowała się i idealnie łączyła z resztą — to byłby koszmar, gdyby wszyscy musieli budować własną skalowalną infrastrukturę. Dlatego istniały zespoły platformowe: browser clients, który zarządzał repozytorium strony, repo aplikacji Electron i mniejszej wersji mobilnej wypychanej wtedy w innych krajach; zespół GraphQL Edge — tak nazywaliśmy API, od którego odbijały się zapytania użytkowników, zanim federowały dalej do mniejszych usług poszczególnych zespołów; były też zespoły platform danych i infrastruktury wideo. I to wymuszało budowanie relacji między produktowcami a platformami, na których stali.

To była jedna z moich ulubionych rzeczy w pracy w takiej firmie: mogłem spędzać większość czasu przy produkcie, a formalnie nigdy nie byłem w zespole platformowym — choć platformowcy powiedzieliby pewnie inaczej, bo wśród nich po prostu mieszkałem. Na przykład jako jedyny nie-platformowiec byłem na cotygodniowych planningach browser clients, bo bardzo mi zależało.

Lekcja Dereka: napraw przyczynę, nie objaw

A zaczęło się od jednej rozmowy. Czytałem dokumentację nowego, reactowego Twitcha, starałem się przenieść jej wskazówki do kodu i wystawiłem PR, który nie był dobry. Pamiętam, że Derek przyszedł do mojego biurka i zaczął pytać, czemu napisałem to tak, a nie inaczej. Pokazałem mu strony dokumentacji, które mnie tam zaprowadziły, i przykłady w bazie kodu, na których się wzorowałem. Podziękował, powiedział, że to bardzo pomocne, wrócił do biurka — i w pół godziny miał dwa PR-y: jeden usuwał śmieci z dokumentacji, które mnie zmyliły, drugi przepisywał mylący kod w repozytorium. Wtedy zrozumiałem, jak ważna jest ta praca: jeśli nie ustawiasz zespołu na sukces, poprzeczka będzie non stop opadać. Każdy PR, który dochodzi do momentu, w którym jest po prostu zły, to sygnał i okazja do poprawy czegoś tak, by następna osoba nie popełniła tego błędu. Jeśli takich okazji nie wykorzystujesz na bieżąco, jakość wszystkiego wokół eroduje zawrotnie. Po raz pierwszy zobaczyłem to w akcji. I jak ujął to ktoś na czacie: nie naprawiaj objawu — napraw przyczynę.

Uwielbiałem to. Dochodziły inne frajdy. Gdy pracowałem nad wewnętrznymi narzędziami bezpieczeństwa (jeszcze nie moderacyjnymi), prowadziliśmy wewnętrzną kopię infrastruktury Twitcha — łatwo było przeskakiwać między narzędziami wewnętrznymi i zewnętrznymi bez przewracania się o różnice. Nasze repo było mniejsze i miało może trzystu użytkowników zamiast milionów, więc mogłem eksperymentować z pomysłami, których nie byliśmy pewni na głównym repo, a potem przychodzić do browser clients: „przetestowaliśmy na własnej skórze cztery pomysły, dwa jakoś działały, jeden wygląda na wart uwagi — zastanówmy się, jak wdrożyć to na stronie”. Oni to uwielbiali. Do dziś moi przyjaciele z Twitcha to w dużej mierze ludzie z browser clients. Kilka razy proponowali mi przejście do nich, ale za bardzo kochałem budowanie produktu. Kocham budować rzeczy, których ludzie naprawdę używają i które odrobinę upraszczają im życie. Nie lubię platformy, jeśli nie poprawia produktu — i nie lubię produktu na słabej platformie, zresztą takiej, która przestała się doskonalić. To napięcie między robieniem produktu rozwiązującego realne problemy a budowaniem podłoża, na którym produkt może rosnąć, ukształtowało sposób, w jaki pracuję do dziś.

I wracam do tego wspomnienia ostatnio bardzo często, bo próbuję zrozumieć, czemu tak szybko przeszedłem na pracę z agentami. Już widzę komentarz: „Theo tak szybko przeszedł na agentów, bo pisał błotnisty JavaScript i nie obchodzi go jakość kodu”. Mam nadzieję, że to, co opisuję, pokazuje dokładnie odwrotnie: jakość kodu jest w równym stopniu kwestią komunikacji i organizacji, co samego pisania i klasy inżynierów. W idealnym świecie przeciętny inżynier i fenomenalny inżynier powinni móc scalić kod, który nie degraduje jakości bazy.

Zanim pójdziemy dalej, odnotujmy, czego nie powiedziałem. Nie mówiłem o zostaniu menedżerem. Nie mówiłem o bardzo restrykcyjnych procesach code review. Nie mówiłem o barierkach i testach jednostkowych wymuszających określone zachowania. Ani o pokryciu kodu. Mówiłem wyłącznie o relacji: platforma, z której może wyrosnąć dobry produkt, i produkt, który daje platformie informację zwrotną — żeby rosły razem.

Firma jednoosobowa i narodziny T3

Co było dalej? Odszedłem z Twitcha. To był duży katalizator — nie tylko dlatego, że zostałem bez pracy, ale dlatego, że zmieniło się „dlaczego” tego, co robię. Na Twitchu dbałem o platformę po to, by moim współpracownikom szło lepiej, by inne zespoły robiły lepszy produkt; zmieniając podłoże, podnosiłem wszystkich wokół. Wszystko, co tam robiłem, służyło łatwiejszemu dostarczaniu dobrych rzeczy przez nas wszystkich. Nie chodziło o szybkość jako taką — choć bywała miłym efektem ubocznym (regularnie wzywano mnie, żeby ratować rozjechane harmonogramy). Chciałem po prostu tak zbudować platformę, by właściwa droga była najłatwiejsza, a przykłady drogi złej — nie istniały.

A potem przeszedłem z firmy półtoratysięcznej do jednoosobowej: mnie. Priorytety musiały się zmienić. Nie mam już zespołu browser clients, który upewni się, że pakiet Webpacka działa we wszystkich konfiguracjach. Nie mam zespołu backendu wideo ani GraphQL Edge. Moim pierwszym odruchem było odtworzyć ich pracę — zbudować wszystko, co kocham. Stawiałem backendy GraphQL na Elixirze, budowałem szalenie złożone bundele klienckie, ręcznie zarządzałem ich dzieleniem. Udało mi się zrobić produkt, który jakoś działał, ale wykonywałem prace wszystkich tych ludzi, którzy przestali być moimi współpracownikami. Zrozumiałem, że muszę zmienić myślenie: nadal chciałem ustawiać całą bazę kodu na sukces — żeby właściwa rzecz była łatwa, a niewłaściwa trudna — ale wszystko musiało stać się szybsze, łatwiejsze i tańsze w utrzymaniu.

I wtedy wydarzyło się coś, o czym wiedzą ci, którzy są tu od dłuższego czasu: T3 stack. Powstał, bo potrzebowałem pewności platform, do których byłem przyzwyczajony, bez tarcia związanego z ich wznoszeniem. Mojej innowacyjności nie należy przesadzać — wziąłem trzy zestawy narzędzi, których ludzie używali z powodzeniem, i złożyłem w jeden: klient na React i TypeScripcie, Next.js jako serwer. Do tego Tailwind, bo mniej więcej wtedy zacząłem go lubić. Najważniejsze było jednak to, jak frontend współpracował z backendem. Z bazy danych aż po backend miałem pełne bezpieczeństwo typów dzięki Prismie. A między backendem a frontendem użyłem nowego narzędzia, w którym się zakochałem — tRPC. Pozwalało zdefiniować funkcje po stronie serwera w TypeScripcie i wywoływać je z frontendu bez definiowania stosu kontraktów. Kontrakt oczywiście powstawał — ale był nim po prostu TypeScript, a nie inny język, jak GraphQL, czy dziwny standard, jak OpenAPI.

To właśnie wystrzeliło mnie na YouTube. Pierwszy film był de facto streamem, na którym tłumaczyłem ten stack ludziom poznanym na Twitterze, gdy byłem nikim. A tak — czacie, pamiętacie dobrze — tRPC poznałem, bo Tanner Linsley zadał mi go jako pracę domową: zobaczył, że obserwują mnie Fred K. Schott (twórca Astro) i Ryan Carniato (twórca SolidJS), i gdy poprosiłem o głos w jego Twitter Space, podzielił się nim ze mną. Rozmawialiśmy o moich dziwacznych propozycjach ułatwienia kontraktów między backendem i frontendem, on rzucił tRPC, ja poszedł to zgłębić i natychmiast się zakochałem. Alex, główny autor tRPC, do dziś jest moim dobrym przyjacielem. Z tej właśnie społeczności pochodzi Julius, dziś człowiek od T3 Code. Tyle rzeczy wynikło z tego jednego momentu.

A moment wynikł z tego, że kochałem uczucie budowania na platformie, którą się rozumie i której ufa się w całości. T3 stack wyrósł z produktu: budowałem najlepszy stack w Ping, żeby produkt był jak najłatwiejszy w utrzymaniu — równolegle prowadząc kanał, zbierając finansowanie na to, co stało się T3 tools (dziś T3 Code i T3 Chat), przechodząc przez Y Combinator i ogarniając sprzedaż z marketingiem. Nie mogłem spędzać po 10–15 godzin dziennie na kodowaniu, więc wkładałem mnóstwo wysiłku w to, by w chwili, gdy już siadałem do kodu, było oczywiste, gdzie powinien pójść czas. Dzielił się on mniej więcej pół na pół: kod platformowy ułatwiający pracę nad Ping i kod produktowy. Brzmi to absurdalnie: połowa PR-ów samotnego dewelopera nie miała żadnego znaczenia dla użytkowników. Nie widzieli żadnej różnicy. Ale ta połowa sprawiała, że druga połowa lądowała znacznie łatwiej.

To wahadło — bujanie się między tymi stronami — towarzyszy mi od tamtej pory i podniosło mnie w zawodzie bardziej niż niemal cokolwiek innego: umieć wycofać się z produktu, gdy staje się trudniejszy, niż powinien być; odejść na chwilę, poprawić platformę; a gdy znów jest w dobrej formie — wrócić i zbudować funkcję. I nie traktować tych stron jako osobnych ról czy zespołów, tylko zacierać między nimi granice. Dlatego zdobyłem na Twitchu przyjaciół, których zdobyłem: byłem ulubionym produktowcem platformowców i — dla ludzi z produktu — oknem na platformę.

Jedna rozmowa zamiast tygodni tarcia

Nie zliczę, ile razy utykałem na spotkaniu produktowym, bo ktoś — inżynier albo lider — był przekonany, że zespół GraphQL Edge „nigdy na to nie pozwoli”, a rzecz była ewidentnie słuszna. Wskakiwałem więc na szybką rozmowę z Toniym, który tym zespołem kierował. Mówiłem: „Pewnie nie jestem właściwą osobą, bo nie jestem backendowcem, ale mój zespół jest przekonany, że struktura danych potrzebna do układu dashboardu — który z natury jest zagnieżdżony, bo wszystko jest mobilne i warstwowe — najlepiej zapisuje się po prostu jako blob JSON. A chłopaki upierają się, że GraphQL nie pozwoli nam włożyć bloba do API i musimy budować skomplikowany system węzłów, pobierać płaską tablicę i składać z niej dynamiczny układ”. Nie mówiłem mu, jakie opcje rozważaliśmy. Powiedziałem tylko, na czym polega problem. Przerwał mi: „To czemu po prostu nie zapiszecie tego bloba?”. Zapytałem, czy jest jakiś powód, żeby nie. Pomyślał chwilę: „Nie. To wygląda na właściwe rozwiązanie”. — „Dobrze, to jak mam przekonać do tego zespół?”. — „Nie wiem. Nikt z nich nigdy do mnie nie napisał”.

A potem się wygadał: resztę rozmowy Tony spędził na tym, jak frustrujące jest siedzieć po stronie platformy, w krainie GraphQL, i czuć, że nikogo z produktu nie obchodzi, co on robi, i że cały dzień spędza na mówieniu „nie” kiepskim PR-om. Był tak wdzięczny, że ktoś z front-endu, z produktu, sam do niego zadzwonił, że gadaliśmy potem regularnie. Do dziś Tony jest bardzo dobrym przyjacielem — o ile dobrze pamiętam, prowadzi dziś dużą część platformy w Netfliksie.

Te rozmowy ukształtowały mnie najbardziej. Zrozumienie, że tak wiele kawałków tarcia, na które natrafiasz jako deweloper, dzieli od zniknięcia jedną rozmowę i jedną małą zmianę w platformie. I że to wszystko jest gigantycznym marnowaniem czasu. Włożyłem więcej wysiłku w same rozmowy o zapisaniu bloba JSON niż w zbudowanie całego dashboardu. Zrobiłem się od tego nieswój. Część tego była polityką wewnętrzną — każda decyzja ważyła koszty polityczne: co jest gorsze, wymyślić własny system węzłów dla dość prostej struktury danych czy zaryzykować odmowę i stracony czas? Ale dużo było po prostu braku wzajemnego zrozumienia obu stron. Dlatego tak głęboko zacierałem te granice — i myślę, że to główne źródło mojej frajdy.

Ostatni wielki remont pisany ręcznie

Przeskoczmy daleko w przyszłość. Zamiast o początkach — o końcu czegoś. O moim ostatnim wielkim, ręcznym remoncie; prawdopodobnie ostatnim w życiu momentem, w którym siadłem i przebudowałem coś od zera samodzielnie, bo kilka prób z pomocą agentów spełzło na niczym, więc odpuściłem i zrobiłem wszystko własnymi rękami.

Ktoś na czacie już zgadł: T3 Chat i Convex. Podchodziłem do Convex z dużą nieufnością — wyglądał wtedy na zamkniętoźródłową alternatywę dla mojego T3 stack. Od tamtej pory Convex otworzył kod i dojrzał bardziej niż cokolwiek, co zbudowałem w tej kategorii: to połączenie backendu, bazy danych, warstwy API i SDK dla klienta i serwera. Do dziś mój ulubiony sposób budowania pełnych aplikacji.

Zanim przeszedłem na Convex w T3 Chat, budowałem autorski silnik synchronizacji — ręcznie. Działał, ale utrzymanie było koszmarem. Port T3 Chat z tego silnika na Convex to jeden z najbardziej porośniętych i najtrudniejszych remontów w moim życiu. Kiedy w końcu scalałem PR-a na ponad 25 tysięcy linii, większość ludzi nie poczuła różnicy — poza tym, że przy jednoczesnym użyciu telefonu i komputera dane częściej trzymały się w synchronizacji. Najwięcej w życiu pracowałem nad jedną zmianą technologiczną. Poświęciłem na to cały miesiąc: zacząłem go z COVID-em, a pod koniec dowiedziałem się, że czeka mnie rekonstrukcja ręki. Wiedziałem więc, że to będzie mój ostatni raz przy kodzie przez jakiś czas. Miesiąc miał ostre krawędzie: byliśmy wtedy jednym z największych klientów Convex i łamaliśmy różne dziwne rzeczy, których inni nie robili. Ekipa Convex szybko to wygładzała. Ale ile to było roboty — i ile frajdy! A użytkownicy nie mogli zauważyć żadnej różnicy, dopóki wszystko nie wylądowało; dopiero potem zaczęła się zabawa.

Dlaczego to zrobiłem? Nie dlatego, że męczyło mnie utrzymanie autorskiego syncu — choć męczyło. Nie dlatego, że koszty bazy przy moim podejściu były absurdalne — choć były. Zrobiłem to, bo powiększyliśmy zespół: ściągnąłem Juliusa na pełen etat, Mark gasił po mnie pożary, a backendem bazy danych mógł się zajmować wyłącznie ja — bo to była „właściwa na tamten moment” platforma, którą rozumiałem tylko ja. Blokowałem więc cały zespół, a wszystko było kruche i ciągle się sypało. Przejście na Convex to naprawiło — i dzięki temu, gdy przez kilka miesięcy nie mogłem kodować z powodu ręki, nadal rozwijaliśmy T3 Chat i dowoziliśmy ulepszenia.

Mówiąc szczerze: kocham takie remonty — te, których nikt z zewnątrz nie może ani nie powinien odczuć, ale które stawiają nas na znacznie efektywniejszych nogach. A potem patrzeć na przyspieszenie, które zyskujemy po stronie produktu. Najbardziej ekscytujące w tamtym remoncie było oglądanie, ile więcej PR-ów Mark i Julius wystawiali i scalali dzięki temu, że mogli swobodniej poruszać się po bazie kodu.

Mam nadzieję, że już widzicie, dokąd zmierzam.

Slop blokuje zespół — także agentów

Pisałem slop zanim agenty w ogóle weszły na scenę (przez slop rozumiem kod niskiej jakości wyrabiany masowo). Nasza architektura T3 Chat przed Convexem to był slop autorskiego silnika synchronizacji Theo — i ciągle rodził tarcie. Wchodził w drogę zespołu. Po prostu nie był dobry. Byłem za to niezwykle wydajnym kucharzem, jeśli chodziło o gotowanie takiego wynalazku. Już wtedy nie broniłbym tego, jak to było zrobione — broniłbym tylko tego, dlaczego. I stąd moje pięć filmów o zmianach bazy danych w T3 Chat: wspaniała okazja do próbowania różnych rzeczy, nauki i budowania skalowalnej platformy w absurdalnym tempie, równolegle z kanałem i firmą. Uwielbiałem tę erę, każdą jej chwilę. Ale najważniejsze w moim slopie jest to, że blokował mój zespół.

Bo prawda jest taka, że nie ma znaczenia, skąd bierze się slop. Ani to, kim jest twój zespół. Przeformułujmy to: slop Sonnet 4.5 blokował Opusa 5.5. (Informacja dodatkowa: Sonnet i Opus to modele Anthropic — odpowiednio starszy i nowszy.) Widzicie już, dokąd zmierzam?

Cały ten czas i wysiłek po „platformowej” stronie — ustawianie zespołu i siebie na sukces — kochałem zawsze, bo widziałem wpływ na drugiej stronie. Efekt pojawiał się powoli, zmiany trwały długo, ale to była satysfakcjonująca robota, przy której czułem się inżynierem. Ta praca stała się dziesięć razy ważniejsza niż kiedykolwiek.

Rachunek opłacalności się odwrócił

Przypominam sobie jedną z pierwszych rozmów, przy których czułem, że nie powinno mi być wolno w niej uczestniczyć. Tweetowałem, mając może pięćdziesięciu obserwujących, o problemach z TypeScripem na Twitchu: pełne sprawdzanie typów trwało 15–20 minut, a start serwera deweloperskiego — trzy do pięciu minut, żeby w ogóle zacząć pracę w losowy dzień. Byłem tak zdesperowany, że po prostu odpisałem na Twitterze Danielowi Rosenwasserowi z zespołu TypeScript, pytając o szczegóły wydajnościowe, o których pisał. Napisał do mnie w wiadomości prywatnej, pogadaliśmy — i to ja pośredniczyłem w spotkaniu jego zespołu z browser clients. Dwudziestolatek, który czuł, że nie należy nigdzie, nagle skleja rozmowę między platformą Twitcha a zespołem TypeScript. To był moment „aha”: wszystko to jest miękkie. Wszystko da się zmienić i poprawić. Wszystko zrobili ludzie nie bardziej wyjątkowi niż ty czy ja — z którymi można po prostu porozmawiać i coś razem zmienić. I do dziś: gdy niedawno wypuściłem TS Rust, zespół TypeScript sam się odezwał; zrobiliśmy świetną rozmowę i mogłem gawędzić z Andersem Hejlsbergiem, twórcą języka, który odmienił moje życie.

Przywołuję to, bo to samo nastawienie — które kazało mi odpisać Rosenwasserowi — doprowadziło do TS Rust. A najdobitniej opisuję je słowem: ogrodnictwo. Używam metafory ogrodu, żeby podkreślić jedno: to nie my mamy teraz „hodować” kod. Mamy budować środowiska, w których kod rośnie we właściwym kierunku — z właściwymi składnikami odżywczymi, systemami podparcia i monitoringiem — tak, żeby roślinka miała jak największą szansę urosnąć, a ty miał jak największą szansę uratować ją, zanim stanie się chwastem zarażającym cały ogród. Wiem to, bo robiłem to już wcześniej: poprawianie czasów sprawdzania typów na Twitchu służyło temu, żeby wszyscy mogli łatwiej pracować w bazie, szybciej sprawdzać, pewniej ruszać i rosnąć.

Kilka miesięcy temu, pracując nad T3 Code, patrzyłem, ile czasu zjada nasze CI i ile RAM i CPU pochłania typowanie na mojej maszynie. Nawet mimo przeniesienia kompilatora TypeScriptu do Go, T3 Code to gigantyczny projekt i sprawdzanie typów kosztowało dużo mocy obliczeniowej. Jeszcze niedawno wysiłek potrzebny do poprawy był tak wielki, a korzyść tak mała, że rzadko się to opłacało. Na Twitchu mogliśmy przepisać TypeScript do Go już wtedy — mieliśmy świetnych inżynierów Go i mogliśmy przeznaczyć dwadzieścia osób, zanim zespół TypeScript pomyślał o tym samym. Ale to byłoby przedsięwzięcie tak absurdalne, że nie uzasadniałoby odciążenia 600–800 front-endowców z czekaniem na start dev serwera. Dziś przepisuję TypeScript w Ruście, żeby trzyosobowy zespół mógł poruszać się odrobinę szybciej. Trudne? Tak. Ale robię to. Rachunek kosztów i korzyści wygląda zupełnie inaczej.

(Informacja dodatkowa: zespół Microsoftu przeprowadza port kompilatora TypeScriptu na Go, by przyspieszyć sprawdzanie typów; TS Rust to niezależna inicjatywa Theo, realizująca analogiczny pomysł w Rustcie.)

Jeszcze jeden przykład. Na Twitchu, żeby mocniej wejść w hooki, musieliśmy przejść z Apollo GraphQL 2 na 3 po stronie klienta. Wychodziło przy tym mnóstwo „dziedzictwa”, którego używaliśmy masowo. Zrobiliśmy jeden wspólny PR z przejściem na Apollo 3, każdy popsuty plik TypeScriptu wrzuciliśmy do arkusza Google, posortowaliśmy alfabetycznie, braliśmy z niego kawałki jako wolontariusze i ręcznie naprawialiśmy błędy typów plik po pliku, a potem testowaliśmy. Tysiące plików w gigantycznym repo. Dosłownie używaliśmy arkusza kalkulacyjnego, żeby ogarnąć, kto co poprawia. Zespół ośmiu osób plus pomocnicy, ponad miesiąc roboty — żeby zmienić jedną paczkę: klient GraphQL, czyli to jedno narzędzie, które pozwala nam definiować zapytania i pobierać dane. Dziś to jeden prompt.

Historycznie taka ogrodnicza praca opłacała się tylko przy gigantycznej skali i gigantycznym tarciu — i zdarzała się w dużych firmach, które poprawnie rozdzieliły platformę od produktu. Firm, które tego podziału nie zrobiły, jest mnóstwo: ich inżynierowie produktu utknęli w pracy platformowej, której zbyt dobrze nie rozumieją, i po prostu nie nadążają. Ale rachunek się zmienił.

Dlaczego agenci cierpią bardziej niż my

Sugerowałem, że agenty ułatwiają takie zmiany i takie wygrane. To jedna strona równania. Druga jest może ciekawsza. Wszystko, co blokowało i spowalniało mnie oraz moich ludzi, było co najwyżej irytujące: z tymi zepsutymi rzeczami składałem może dziesięć PR-ów tygodniowo, a po naprawach dwanaście, piętnaście. Agent te same rzeczy blokują dużo mocniej. Jeśli wystartowanie dev serwera, żeby w ogóle sprawdzić, czy kod działa, zajmuje pięć minut, agent utknie w tym głęboko. Do tego przy pięciominutowych TTL-ach marnujesz kupę tokenów, bo czekając tak długo na walidację zmiany, nie trafiasz w odczyty z pamięci podręcznej. Za wolne CI albo zbyt wielkie zużycie RAM i CPU ogranicza, ile pracy da się zrównoleglić. Za wolna ścieżka wydawnicza — gdy boisz się releasu, bo trwa długo albo, co gorsza, może nieść coś złego, a następny release naprawczy będzie trwał jeszcze dłużej — oznacza mniej scalonych zmian. Stała pielęgnacja platformy nigdy nie była ważniejsza, bo jej brak blokuje agentów mocniej, niż blokował nas.

I jest jeden naprawdę duży powód, którego ciągle nie nazwałem: slop rośnie szybciej niż chwasty. Jeśli nie pielęgnujesz ogrodu bez przerwy, bardzo szybko wrócisz do ogródka złożonego głównie z chwastów. To jest problem, który niszczy dziś tak wiele. I to jest właściwie nasza praca. Mamy spędzać mnóstwo czasu, upewniając się, że do ogrodu trafia właściwy nawóz. Mamy stawiać paliki i owijać roślinki, żeby rosły pionowo i nie łamały się w okropny sposób. I mamy wyrywać chwasty, ledwie je zauważymy.

Ogrodnictwo w praktyce: trzy przykłady

Żeby pokazać, o jakiej pracy mówię: oto PR, z którego jestem szczególnie dumny. Usunąłem w nim około połowę wszystkich testów jednostkowych w T3 Code. Im dłużej w niej pracowałem, tym wyraźniej widziałem, ile z tych testów jest bezwartościowych — a co gorsza, jak bezwartościowe testy się namnażają i generują coraz więcej zbędnych przypadków brzegowych, testowanych bez żadnego powodu. W jednym PR usunąłem 250 tysięcy linii kodu. Nie było ani jednej regresji, którą którykolwiek ze skasowanych testów by wyłapał. Z jedenastu tysięcy testów przywróciłem łącznie cztery. To jest fenomenalny przykład ogrodnictwa. Taka jest nasza praca.

Naturalne pytanie: jak zapobiegać odrostowi? Monitorując. Zrobiliśmy kilka zmian w wytycznych dla agentów, żeby odciągać je od tworzenia złych testów. Ale samo skasowanie całego slopu bardzo pomogło. Złe testy i tak wyrastały tu i ówdzie, więc gdy któryś z nas taki zauważył, prosiliśmy autora zmiany o znalezienie wątku, w którym powstał, i zapytanie własnego agenta: co skłoniło cię do dodania tego testu? Czemu uznałeś go za dobry pomysł? Z odpowiedzi szliśmy do źródła — do łodygi, z której ten chwast wyrósł — i uśmiercaliśmy ją.

Inny przykład, jeden z moich ulubionych. Męczyły mnie regresje wydajnościowe w protokole przesyłu danych — tym, którym wszystko, co widzisz w aplikacji, płynie z serwera do klienta na twoim telefonie czy komputerze. Włożyłem kupę pracy, by nawet duży wątek ważył jakieś pięć kilobajtów, ale wyniki ciągle się psuły: po tygodniu ulepszania wydajności subtelne, małe PR-y, które z pozoru nie miały tu nic do gadania, robiły krzywdę. Zbudowałem więc „thread transfer impact tool”: kontrolę uruchamianą na każdym PR, która bierze garść prawdziwych danych zdarzeń z prawdziwych wątków Codexa i Claude, przepuszcza je przez symulację całego potoku od serwera do klienta i mierzy, ile danych przelatuje przez cały ciąg — a wynik drukuje w każdym PR i stawia wielkie czerwone krzyżyki, gdy cokolwiek powoduje istotną regresję. To zadziałało znakomicie z kilku powodów. Informacja zwrotna w samym PR zostaje zauważona i obsłużona przez agenta, który nad nim czuwa. Programiści i recenzenci dostają jasny sygnał, czy metryka, na której nam zależy, się zmienia. Ale najważniejsze — i brzmi to głupio — to po prostu daje agentowi do zrozumienia: ta rzecz jest dla nas ważna i warto ją optymalizować. Wracając do metafory: to drewniany palik wbity obok roślinki, żeby rósł we właściwą stronę. Ta jedna kontrola w CI — zajmuje niecałe 45 sekund, może 30 — okazała się jednym z najużyteczniejszych palików w moim ogrodzie, prowadzących rośliny właściwie, z dala od chwastów.

Wiecie, ile frajdy daje taka robota? Wiem, że jestem trochę świrkiem od protokołów, ale uwielbiam reprezentacje danych i dobieranie właściwego zestawu informacji przesyłanych między platformami, produktami i funkcjami. Ta część mojego mózgu nigdy nie była tak cenna. Znaczna większość mojej pracy nad T3 Chat po drugim miesiącu to odblokowywanie zespołu — poprawianie platformy, żeby wszyscy inni mogli budować funkcje, których potrzebowali użytkownicy. Teraz robię to samo z agentami i dla agentów: buduję najlepszą możliwą bazę kodu do współtworzenia. Bywa w niej żmudno, bywają ostre kontrole, ale to najlepszy ogród, jaki kiedykolwiek widziałem — nie wspominając o pracy w nim. I bez przerwy, wielokrotnie sprawdzam swoich agentów: gdzie utykają, o jakie chwasty się potykają, jaki nawóz je myli, jakich palików im trzeba. Jeśli nie uważasz tego za inżynierię, to nie wiem, czy kiedykolwiek byłeś inżynierem — bo nigdy nie czułem się bardziej jak ktoś, kto buduje platformę, niż dziś. I to jest cholernie fajne. Nawet jeśli nie kochasz utrzymania i roboty platformowej, pokochasz to, co dzieje się po drugiej stronie. To była magia, która sprawiła, że przestałem robić to dla samego robienia, a zacząłem niemal żałować każdej sekundy spędzonej na czymś innym — bo widziałem wpływ.

Gdy ogród jest zdrowy

Proszę bardzo: PR scalane dziennie od początku T3 Code. Moja twarz zasłania te pionowe linie właśnie dlatego, że są takie pionowe. Z dość stabilnych 2–20 PR-ów dziennie przeszliśmy do 60 w słabszy, weekendowy dzień, a w dni aktywne — powyżej 400. Bo nasz ogród jest naprawdę zdrowy. To dzieje się, gdy dbasz o ogród.

Nie chcę wierzyć, że ktoś doszedł tuż przede mną do dokładnie tej samej analogii — dopiero teraz się dowiaduję. Podobno nie jestem tak unikalny, jak mi się wydawało. A Lauren i ja jesteśmy ostatnio podejrzanie zgodni. Jej wpis, który czat mi właśnie wygrzebał: „Każdy zespół potrzebuje ogrodnika. Kogoś, kto cicho patrzy na strumień PR-ów wpływających do bazy i wyczuwa code smells. Trzecie takie coś w tym tygodniu. Tłumione ostrzeżenia lintera, pełzające jak bluszcz po starannie zaplanowanym ogrodzie. Stała dłoń, wyrywająca chwasty, które — gdy je zignorujesz — zatopią wszystko w slopie”. Gdybym mówił dalej, ten film nie skończyłby się nigdy.

Na koniec

Dajcie znać, czy wam się podobało — i czy dadzicie radę przegadać irytujących komentujących, bo wiem, że pod tym odcinkiem będą irytujący. Jeśli podobało się wam na tyle, że chcielibyście więcej takich materiałów, powiedzcie. Chętnie opowiem szerzej o technikach, których używam do pielęgnowania ogrodu i utrzymywania baz kodu przyjaznych do pracy. Część z nich działa świetnie, przy części jeszcze nie wiem. Ale to naprawdę fajny czas na próbowanie. Nigdy nie czerpałem z pracy tyle radości co dziś, i mam nadzieję, że coś z tego pomoże wam czerpać tyle samo. Wiem, że ten świat zmienia się bardzo szybko i że bywa strasznie. Ale jeśli znajdziecie w nim magię, to jest to jednocześnie najzabawniejszy okres w historii. I jeśli choć jedna osoba zobaczy teraz magię tam, gdzie wcześniej by jej nie dostrzegła — było warto nadstawić głowę na hejterskie komentarze.

Trzymajcie się, nerdzi.