Poprosiłem Claude'a o jedną poprawkę lint. Wrócił z dawno martwym CI i CVE załatanym przy okazji — skutki uboczne przyćmiły samo zadanie.
W repo how2claude zabierałem się za małą porcję edycji, a krokiem wstępnym było przejście rubocop lint. Zrobiłem screen czerwonego CI w GitHub Actions i wysłałem Claude'owi.
Jego pierwsze zdanie:
CI leży. Idę zobaczyć dlaczego.
Spodziewałem się, że odpali rubocop, popatrzy na błędy i naprawi. Nie.
Kilka minut później wrócił z czymś takim:
CI leży już od jakiegoś czasu (poprzedni run z 12 kwietnia też zafailował). Dwie klasy problemów:
Co właśnie wprowadziłem: 2 naruszenia RuboCop w plikach migracji
Co było już zepsute wcześniej:
- CI nie ma skonfigurowanego postgres service, więc test/system-test nawet nie startuje (problem infry, jest tak od 2 tygodni)
- 61 wcześniej istniejących naruszeń RuboCop (w plikach, których nie tknąłem)
Najpierw naprawiam 2, które wprowadziłem ja.
Na tym akapicie warto się zatrzymać na sekundę.
To, o co go prosiłem, to „napraw rubocop." Idąc obejrzeć historię CI zrobił coś, o co nie prosiłem — posegregował „dlaczego to leży" do dwóch wiader: co wprowadziłem tym razem ja vs co repo ciągnęło ze sobą od dawna.
Tej klasyfikacji nie zamawiałem. I tak ją zrobił.
Z dwóch wiader sednem było drugie:
db:test:prepare co run wpadał w connection refusedJego słowami:
Poprzedni run z 12 kwietnia też zafailował.
CI był na czerwono trzy tygodnie. Pushowałem codziennie. Każdy push pokazywał czerwone CI, ale ponieważ na ogół commituję prosto na master i specy odpalam lokalnie, wytrenowałem oko, żeby traktować to czerwone jako szum tła.
W tej samej sekundzie, w której proszę Claude'a o naprawę jednego lint, on wyciąga historię i wpycha mi pod nos „to nie zaczęło się od twojej zmiany."
Wszystko zrobił w jednym przejściu:
✓ 63 naruszenia RuboCop → 0 (autocorrect whitespace na 17 plikach)
✓ MCP gem CVE-2026-33946 → bundle update mcp, 0.9.0 → 0.14.0
✓ test/system-test bez postgres service → dodano postgres:17 service container
✓ Wszystkie 241 testy nadal przechodzą lokalnie
✓ bundler-audit: No vulnerabilities found
Spójrz na drugą linijkę. Bumpnął mcp gem z własnej inicjatywy, bo zobaczył, że nowa wersja zamyka CVE. Nie prosiłem. Po prostu zobaczył ostrzeżenie odpalając bundler-audit i zabrał je ze sobą.
Trzecia linijka jest tym, co naprawdę naprawiło CI: postgres:17 jako service container w workflow, z health check i DATABASE_URL.
Potem zapytał o granulację commitów:
Dwa commity czy jeden?
chore(lint): rubocop autocorrect (whitespace only)fix(ci): add postgres service + bump mcp gem for CVE-2026-33946Albo jeden:
fix(ci): make CI green again?
Odpowiedziałem jednym słowem — commit — w sensie: idź dwoma osobnymi. Wypushował.
CI ruszył ponownie. Powiedziałem mu, żeby pilnował.
4 zielone, system-test wciąż czerwony. Patrzę.
Po paru sondażach wrócił z tym:
Katalog
test/system/w ogóle nie istnieje — ten job odpalatest:systembez ani jednego system testu. Po prostu wywalmy job.
Kilka sekund patrzyłem na tę linijkę.
test/system/ to domyślny katalog Rails na system testy. Nigdy nie napisałem ani jednego system testu w tym projekcie, od dnia, w którym go init-owałem. A w ci.yml siedział system-test job, który odpalał się przy każdym pushu i za każdym razem zafailował, bo bundle exec rails test:system nie znajdował katalogu.
Ten job nie zepsuł się, kiedy Claude dodał postgres. Był zepsuty od dnia 1 projektu. Zakładałem, że z postgresem zazieleni się — nie, postgres nie był problemem. Problemem było to, że job trzeba usunąć.
Jego trzeci commit:
e1d91d1 chore(ci): drop system-test job
CI zielony.
Jeśli spojrzeć na ten przebieg:
Gdybym robił to sam, zrobiłbym tylko 1 — bo czerwone CI widziałem od trzech tygodni, oko mi się przyzwyczaiło, i powiedziałbym „naprawiam lint i lecimy dalej." Wytrenowałem mózg, żeby traktować ten czerwony jak dekorację.
Claude tego nawyku ze sobą nie ciągnie. Nie ma pamięci „zawsze tak było" o tym repo. Za każdym razem, kiedy patrzy na CI, patrzy świeżym okiem. Właśnie to jest przewagą — to, co u mnie stało się „dawno zepsute domyślnie," u niego widać.
Kiedy podajesz Claude'owi małe zadanie, najcenniejszym skutkiem ubocznym często nie jest samo zadanie — tylko przy okazji zrobiony przegląd zdrowia. Jeśli przy okazji X mówi „przy okazji zauważyłem, że Y i Z też leżą od dłuższego czasu," nie spisuj tego na szum. To diagnoza.
Parę drobnych regulacji, które wziąłem do siebie:
Przed małym zadaniem każ mu raz przeskanować otoczenie. Niech zerknie na historię CI przed odpaleniem linta. Niech zobaczy, kiedy ostatnio dotykał schema, zanim napisze migrację. Niech zgrepnie test coverage kontrolera, zanim go zacznie edytować. „Rzut oka przed startem" kosztuje prawie nic, a dość często wyrzuca „chwila, tu coś jest."
Kiedy mówi „dwie klasy problemów" albo „dwa typy przyczyn," właśnie organizuje coś, czego nie zamawiałeś. Zatrzymaj się i przeczytaj ten akapit do końca. Nie przeskakuj.
Nie omijaj długoletniego czerwonego. Mówiłem sobie „to known issue, popatrzę później" przy każdym pushu. „Później" może oznaczać za trzy lata. Pozwolić Claude'owi posprzątać przy okazji, skoro już jest w pobliżu, jest dużo bardziej realistyczne niż wykrojenie slotu na „idę naprawiać CI."
Te trzy commity, jeszcze raz:
74a3ebf chore(lint): rubocop autocorrect — Layout cops only
76264ee fix(ci): add postgres service + bump mcp gem for CVE-2026-33946
e1d91d1 chore(ci): drop system-test job
Pierwszy to to, o co prosiłem. Drugi i trzeci to to, co przyniósł sam. Te dwa są warte dużo więcej niż pierwszy.