← Artykuły Harupa
2026-08-02RU EN UA BY PL

My Architect, część 11: osiemset commitów, których nie napisałem

Drugiego sierpnia rano policzyłem commity w swoim generatorze wideo. Wyszło 795. Zanim skończyłem pisać ten artykuł, licznik doszedł do 802. Kodu przez ten czas nie napisałem ani linijki — odpowiadałem na pytania i patrzyłem, co z tego wychodzi.

Przez dziesięć części tej serii opowiadałem, jak zbudowany jest my_architect: pamięć, magazyn, model planowania, cykl pracy, Event Storming, graf kodu. Cały ten czas słuszny był zarzut: ładnie, ale pokaż to na prawdziwym projekcie. Pokazuję.

Wszystkie liczby poniżej zdjąłem z żywego projektu 2 sierpnia 2026 roku. Tam, gdzie liczba mierzy nie to, co się na pierwszy rzut oka wydaje, piszę o tym wprost.

Projekt, który nie mieści się w głowie

Generator wideo — czyli Vini Studio — zaczął się 16 maja 2026 roku commitem z wiadomością init. Na drugiego sierpnia to 802 commity w 78 dni, 920 plików pod gitem, 85 tysięcy linii kodu i jeszcze 70 tysięcy linii dokumentacji i configów.

Różnorodność jest tam nieprzyzwoita jak na jedną osobę. Front: React 18 na litegraph, nodowe płótno z 25 typami nodów. Backend: Node bez frameworka, 2771 linii w jednym routerze, SQLite na 16 tabel. Render idzie przez Remotion, a ten podnosi Chrome Headless Shell. Obok żyją dwa pythonowe sidecary na Flasku: pierwszy jest owinięty wokół ffmpega i trzyma 17 endpointów, drugi rozdziela ścieżki przez Demucs na torchu. Modeli — pięciu dostawców: fal.ai, Anthropic, OpenAI, Groq, ElevenLabs, plus dwa rejestry po sześć modeli każdy, dla wideo i dla obrazów. Jest jeszcze warstwa badawcza: dziewiętnaście dokumentów research, trójwarstwowe evale zachowań, ślepa ocena scenarzystów w poprzek dostawców i pięć pomiarów A/B, w których decyzję podejmowały liczby.

A 24 lipca projekt w ogóle zmienił całą architekturę. Pierwsza droga montażu, telegramowy bot na n8n, poszła do archiwum decyzją RFC-055, kanoniczne stało się nodowe płótno. Dziewiętnaście workflow n8n zostało w gicie już tylko jako historia.

Od razu o tytule, żeby nie było spekulacji. Autorem wszystkich 802 commitów git uważa mnie i commit klikam też ja. Formalny ślad agentowego współautorstwa to trailer Co-Authored-By — stoi w 256 commitach, czyli 31.9%, i jest tam pięć różnych wersji modeli. To dolna granica, bo trailer nie zawsze się pojawia.

Za to tryb pracy nad repozytorium widać dobrze. Siedem worktree, trzy z nich agentowe, założone 19 lipca w odstępie siedmiu minut. A czwartego lipca jest seria 43 commitów w 33 minuty: mechaniczna migracja testów na wspólny harness, commit na plik. Ręcznie tak nie potrafię.

Nie pamiętam tego projektu. Pamiętam kierunek. Cała reszta leży w architekcie.

Co tam naprawdę leży

Zrzut projektu z my_architect na drugiego sierpnia — 650 węzłów. Trzydzieści jeden epików najwyższego poziomu, 237 ficzerów, 33 historie, 324 zadania i 25 bugów założonych osobnym typem. Z tego 527 jest zamkniętych — to 81%. Cztery poziomy hierarchii, sześć koszyków wydań, najstarszy to MVP, zamknięty w całości, 38 z 38.

Wymagań — 296. Nie tylko funkcjonalnych: 241 FR, 26 NFR, 20 ograniczeń, pięć architektonicznie znaczących, trzy systemowe i jedno otwarte pytanie — dokładnie to, które podrzuciłem w dyskusji i które zostało założone właśnie po to, żeby nie przepadło. Dokumentów na węzłach — 29, diagramów — cztery, w tym tablica Event Storming.

Skalę najłatwiej poczuć tak. Kiedy poprosiłem o wyciągnięcie kontekstu projektu jednym wywołaniem, odpowiedź zajęła 258 tysięcy znaków — i to jeszcze widok przycięty, bez opisów węzłów. A lista wymagań w całości nie zmieściła się w ogóle: narzędzie zwróciło błąd „385 tysięcy znaków, przekroczony limit" i położyło odpowiedź na dysku.

I to jest właśnie odpowiedź na pytanie, po co zewnętrzna pamięć. Nie dlatego, że agent jest głupi. Dlatego, że projekt jest fizycznie większy niż jakiekolwiek okno kontekstowe — moje też.

Wymaganie, commit i test trzymają się za ręce

W korzeniu projektu leży CLAUDE.md na 488 linii z jedenastoma twardymi regułami. Jedna z nich wygląda tak:

Każda decyzja architektoniczna, decision, status-change czy scope-shift OBOWIĄZKOWO jest odzwierciedlona w DWÓCH miejscach: RFC w docs/rfc/RFC-NNN-*.md oraz my_architect MCP. Jeśli zmiana nie jest odzwierciedlona w obu — przepadnie przy /compact albo w nowej sesji. Nie rób pracy, której nie zapisałeś. Nie zapisuj pracy, której nie zrobiłeś.

Ostatnie zdanie to nie moja parafraza, tylko dosłowna linijka z repozytorium. I ono działa: 456 commitów z 802, czyli 56.9%, niesie w temacie albo w treści odwołanie do konkretnego FR lub RFC. Plików RFC w projekcie jest 63, od pierwszego do sześćdziesiątego czwartego, z jedną dziurą na czterdziestym szóstym.

Ale sama dyscyplina odwołań nic nie jest warta bez drugiego końca. Drugi koniec to testy. Reguła brzmi tak: każda naprawa regresji przyjeżdża ze stałym testem oznaczonym // covers: FR-NNN naprzeciw wymagania w architekcie, a jeśli wymagania jeszcze nie ma, najpierw się je zakłada.

Dalej zaczyna się mechanika. Skrypt wyciąga wymagania z architekta i zestawia je z tagami w testach. Drugi skrypt wywala build, jeśli przy którymś wymaganiu znalazło się zero pokrywających testów. Uruchomiłem go dosłownie przed chwilą: ALL 203 requirements covered. Tagów // covers: w katalogu testów jest 290 sztuk na 221 unikalnych identyfikatorów. Identyfikatory wymagań żyją też w kodzie produkcyjnym: 145 różnych FR występuje w źródłach płótna.

Jak to wygląda w konkretnym łańcuchu. Jest RFC-052 o usuwaniu projektu. W jego nagłówku — węzeł feature-211-adwcry w architekcie. Węzeł ma pięć wymagań. Po nich dwa commity z 23 lipca, po commitach — funkcje deleteProject i renameProject w storze, a po funkcjach — trzy testy z tagami. A treść pierwszego commita kończy się linijką Architect: feature-211-adwcry → done; NFR-122/FR-143/FR-144/FR-145 → approved. Łańcuch domyka się w obie strony i przejść go można z dowolnego końca.

Przed kodem — obrazek, nie tekst

Jest technika, którą lekceważyłem, dopóki nie zacząłem jej używać bez przerwy: zanim cokolwiek zbudujesz, narysuj to i daj sobie wybrać.

Od 28 czerwca do 3 lipca agent narysował mi czternaście interaktywnych wireframe'ów w HTML w sześciu sesjach burzy mózgów — jakieś 94 kilobajty ręcznie napisanego HTML-a. Nie obrazki: lokalny serwer podnosił je w przeglądarce po kolei, a ja klikałem wariant. Układ powłoki — szyna z dokiem kontra wszystko w górnym panelu. Trzy warianty paska statusu. Gdzie wieszać ikony nad nodem i ile ich ma być. Jak wyglądają stany wskaźnika zapisu. Panel historii.

Kolejność „najpierw obrazek, potem kod" łatwo sprawdzić. Wireframe koncepcji płótna jest datowany na 28 czerwca, pierwszy commit samego płótna — na 29. Speca z 1 lipca mówi dosłownie: „warianty poniżej odzwierciedlają realny wybór użytkownika w przeglądarce, a nie przypuszczenia". Speca z 3 lipca wskazuje, że wzięty został makiet C, a makiet B odrzucono.

Najcenniejszy jest przypadek, w którym makieta doprowadziła do decyzji, żeby nie budować nic: porównaliśmy warianty i zobaczyliśmy, że przewód i tak jest czytelny, node pośredni jest zbędny.

W moich notatkach ta reguła zapisana jest ostrzej, niż zwykle sobie pozwalam: dopóki burza mózgów nie została przeprowadzona i przepracowana — nie trzeba robić nic, będzie tylko gorzej.

Wireframe'y, swoją drogą, leżą w gitignore. Po samym gicie tej praktyki nie widać — co samo w sobie jest niezłą ilustracją, dlaczego pracę trzeba zapisywać nie tylko commitami.

O nocy

Oddaję zadanie o dziesiątej wieczorem, a rano przychodzę do gotowego wyniku. W ostatnich miesiącach — do dużego: nie „popraw margines", tylko złożony kawałek systemu.

Najpierw postanowiłem sprawdzić to po commitach i o mało nie wyciągnąłem błędnego wniosku. W okno od dziesiątej wieczorem do ósmej rano trafia 75 commitów z 802, a od pierwszej w nocy do szóstej rano — dokładnie zero. Wygląda to na zaprzeczenie.

Tyle że commit zapisuje nie moment, w którym praca szła, tylko moment, w którym ją przyjęto. O trzeciej w nocy nie ma jej kto przyjąć. Po timestampach długości autonomicznego przebiegu nie da się zmierzyć w ogóle — ani udowodnić, ani obalić.

Za to kształt doby da się zmierzyć — i mówi dokładnie to, co opisuję. Doba ma dwa garby, a noc leży między nimi. Dziewiąta wieczorem to druga najbardziej obłożona godzina w całej historii projektu, 75 commitów. Dziewiąta rano — trzecia, 70. Na wieczorne oddanie zadań od dziewiątej do północy przypadają 122 commity, na poranny przegląd od siódmej do dziesiątej — 115.

I poranne commity są największe w ciągu doby: średnio 361 wstawionych linii wobec 179 w dzień, dwa razy tyle. W dzień idzie drobna iteracja. Rano do repozytorium przyjeżdża duży kawałek, zrobiony w całości.

Czyli to zdanie nie jest o godzinach. Jest o tym, skąd bierze się pewność, żeby oddać duży kawałek i nad nim nie siedzieć — a to akurat mierzy się wprost.

Pewności nie daje model. Daje ją to, że agent nie ma gdzie skłamać: wymaganie ma numer, numer ma test, a test ma bramkę, która wywala build.

Jak wygląda próba wytrzymałości tego mechanizmu, widać po historii pierwszego sierpnia. Na płótnie było 63 zielonych testów przeglądarkowych, które tworzyły połączenia między nodami przez wywołanie wewnętrznego API. Równolegle z tym żyły dwa bugi, odtwarzalne ręcznie w stu procentach. Jeden test wręcz podrabiał zdarzenie, którego na produkcji nie ma, i był zielony właśnie dlatego, że sam naprawiał sobą dokładnie ten warunek, który jest zepsuty.

Wniosek z tego stał się kolejną twardą regułą: bugi wejścia sprawdza się prawdziwym wejściem przeglądarki — przez realne zdarzenia myszy, z prawdziwym przechwyceniem wskaźnika. Tag // covers: na wymaganiu o interakcji bez prawdziwego wejścia to fałszywa pewność, bo bramka sprawdza linijkę w komentarzu, a nie warstwę, której test naprawdę dotyka.

A skoro obiecałem uczciwość, oto druga połowa obrazu. Maszynowego przymusu synchronizacji u mnie nie ma: hooków nie ma, CI przepuszcza tylko deploy, testy i bramkę pokrycia odpalam ręcznie. Dyscyplina trzyma się na tekście reguł i na tym, że agent czyta je co sesję. Działa — ale to nie to samo, co „nie da się złamać".

Co na tym zyskuję

Moja rola jest przez to inna. Nie opowiadam agentowi kontekstu i nie pamiętam, w jakim stanie jest dwudziesty ósmy epik. Zajmuję się produktem: oglądam filmiki, wyłapuję, co drażni, decyduję, który model wyrzucamy z rejestru i ile to kosztuje w sekundach wideo.

Przez ostatni tydzień lipca i pierwsze dni sierpnia w studiu pojawił się edytor oprawy, w którym podgląd fizycznie nie może rozjechać się z renderem, bo to dosłownie ta sama kompozycja. Pojawiło się studio montażu: od rewizji z 2 sierpnia składa film prosto w karcie przeglądarki. I w dwa dni przyjechał cały kontur głosowy: klon głosu, lektor, izolacja, dubbing, lipsync. Trzy RFC pod rząd zamknięte w trzy doby.

Przy okazji zdarzył się tam incydent, który zwykle nie trafia do raportu o zwycięstwach: 20 lipca nieograniczony render położył pamięciowo cały wspólny serwer, load doszedł do jedenastu na czterech rdzeniach. Leczy się to nudno — sufitem pamięci i procesorów dla kontenera, żeby padał tylko własny render, a nie host. Komentarz z opisem incydentu zostawiłem prosto w configu, żeby nikt potem nie zdjął limitów „bo niepotrzebne".

Dalej — zespół

Powiem wprost, żeby mnie nie zrozumiano na odwrót. To nie jest historia o tym, że jeden człowiek zastępuje zespół. Posadzić jedną osobę przy dużym zespołowym projekcie i liczyć, że wystartuje, dziś się nie da, i ja czegoś takiego nie proponuję.

To historia o tym, dokąd przeprowadziło się wąskie gardło. Wcześniej moim ograniczeniem były ręce. Teraz ograniczeniem jest to, na ile wyraźnie sformułowano, co ma powstać, i na ile maszyna potrafi sprawdzić, że powstało dokładnie to.

I tu jest dla zespołu najciekawsze. Cała dyscyplina, dzięki której agentowi można oddać duży kawałek, to dokładnie te artefakty, których zespół potrzebuje i bez żadnych agentów. Jedno źródło prawdy o stanie pracy zamiast wątku na komunikatorze. Wymaganie z numerem, do którego dosięgasz z kodu, i bramka, która wywala build, jeśli to wymaganie zostało bez testu. W pojedynkę bez tego da się jeszcze żyć, w zespole — nie.

Wcześniej takie artefakty trzeba było zespołowi sprzedawać jako narzut: piszemy wymagania, bo tak wypada. Teraz mają drugiego odbiorcę, który czyta je co sesję i pracuje według nich dosłownie. Ten sam dokument obsługuje i człowieka, i agenta. Czegoś takiego wcześniej nie widziałem — i mnożnik jest właśnie w tym.

Czego na zespole jeszcze nie mierzyłem i uczciwie nazywam otwartym: jak rozjeżdża się tracker, kiedy pisze do niego pięć osób i dziesięć agentów; kto zatwierdza wymaganie, jeśli jego autorem jest agent; ile trzeba review, kiedy ilość kodu na tydzień rośnie wielokrotnie. To następne zadanie, a nie rozwiązane.

Drzwi otwieram, a nie zamykam.

Fakty i linki

Pomiar zrobiony 2 sierpnia 2026 roku. Repozytorium generatora wideo: 802 commity, pierwszy 16 maja 2026, ostatni na moment pomiaru — a2cc612 o 12:50. Dane architekta — żywy projekt ai-video-generator na my-architect.app: 650 węzłów, 296 wymagań, 29 dokumentów, 4 diagramy. Bramka pokrycia — node test/check-coverage.mjs, wyjście „ALL 203 requirements covered". Rozkład commitów po godzinach — git log --format='%ad' --date=format:'%H'; średni rozmiar commita w oknach doby — z git log --shortstat. Wireframe'y leżą w .superpowers/ i do gita nie trafiają, daty wzięte z systemu plików i zestawione z datami spec.

Samo narzędzie — my-architect.app, instaluje się w Claude Code dwiema komendami. Jak zbudowane jest studio, o którym tu mowa, rozbierałem w artykule „Od płótna do studia".

Jeśli prowadzisz podobny projekt z agentami i wyszło ci inaczej — napisz do mnie. Szczególnie ciekawe są przypadki, w których taka dyscyplina nie wypaliła: są bardziej użyteczne niż historie sukcesu.