Instrukcja, która skasowała nie te dwadzieścia sześć języków

Poleciłem automatyzacji własnej strony, żeby zmniejszyła blog do czterech języków. Dwa dni później okazało się, że przy okazji po cichu usunęła dwadzieścia sześć języków także ze strony głównej i nie zauważył tego ani ja, ani żaden odwiedzający.
TL;DR
- Instrukcja skierowana do bloga objęła zamiast tego całą stronę.
- 26 z 30 języków zniknęło ze strony głównej, strony z CV i wszystkich napisów w nawigacji.
- Nic się nie wysypało i żaden link nie zwrócił 404, więc przez dwa dni nikt tego nie zauważył.
- Naprawa wyszła z historii gita, nie z pamięci o tym, jak strona kiedyś wyglądała.
- Prawdziwa lekcja: zanim automatyczna zmiana ruszy, trzeba nazwać dokładną listę plików, których dotknie, i przeczytać tę listę, zanim cokolwiek zostanie skasowane.
Dlaczego w ogóle chciałem mniej języków
Moja strona w ciągu kilku miesięcy urosła do trzydziestu języków: strona główna, strona z CV i blog, który aktualizuję niemal co kilka dni. Pisałem już wcześniej o tym, jak niebezpieczne to potrafi być: tłumaczenie maszynowe brzmi na tyle płynnie, że wygląda dobrze, i jest na tyle błędne, że potrafi zawstydzić, w języku, którego sam nie jesteś w stanie sprawdzić. Strona główna i CV zmieniają się rzadko, więc z tym ryzykiem mogłem tam żyć. Z blogiem sprawa wyglądała inaczej. Nowe wpisy pojawiają się często i naprawdę nie mogę ręczyć za jakość tłumaczenia świeżego artykułu na estoński tego samego dnia, w którym wychodzi.
Zdecydowałem więc ograniczyć liczbę języków, na które tłumaczony jest blog, do czterech, które naprawdę potrafię sam zweryfikować: angielski, rosyjski, niemiecki, czeski. Reszta zostaje poza blogiem, dopóki nie znajdę lepszego sposobu na sprawdzanie jakości. Ta część planu była sensowna. Problem pojawił się w sposobie, w jaki to zleciłem.
Jedno zdanie, zły zakres
Wydałem jedną instrukcję: blog ma zostać przy czterech językach. Krótko i konkretnie, a przynajmniej tak mi się wydawało. To, co faktycznie się wykonało, dotknęło trzech różnych rzeczy naraz. Poprawnie ograniczyło foldery z treścią samego bloga do czterech wskazanych języków. Ale przy okazji nadpisało też główną listę języków całej strony, czyli plik konfiguracyjny, który określa, jakie języki w ogóle istnieją, i usunęło treść strony głównej oraz napisy w nawigacji dla pozostałych dwudziestu sześciu.
Problem w tym, że „blog" i „lista języków całej strony" żyją w tym samym pliku konfiguracyjnym. Nic w tym pliku nie rozróżnia, które języki obsługuje blog, a które strona jako całość. Usuń język z tej listy, a każda sekcja, która z niej korzysta, strona główna włącznie, traci go za jednym zamachem. Moja instrukcja wskazywała sekcję. Zmiana, która faktycznie się wykonała, miała zakres wszystkiego.
I właśnie to sprawiło, że było to niebezpieczne, a nie tylko błędne: nic nie wybuchło z hukiem. Żadnego błędu, żadnego 404, żadnego nieudanego builda. Strona po prostu po cichu przestała generować stronę główną i CV dla dwudziestu sześciu języków, a przełącznik języków przestał je proponować. Odwiedzający, który do tej pory czytał stronę po portugalsku, po prostu bezgłośnie trafiał na wersję angielską. Zniknięcie przez skasowanie wygląda dokładnie tak samo jak nigdy-nieistnienie, i żadne z nich nie rzuca błędem.
Minęły dwa dni, zanim to zauważyłem, i to przypadkiem, w trakcie zupełnie innej poprawki, kiedy link „Blog" w nawigacji dla jednego z języków, które uważałem za wciąż aktywne, prowadził w dziwne miejsce. Ten jeden urwany link był jedynym widocznym tropem prowadzącym do całego problemu.
Co pokazał diff
Prawdziwym błędem nie jest tu sama pomyłka w zakresie. Jest nim to, że nigdy nie sprawdziłem listy plików, których zmiana miała faktycznie dotknąć, zanim pozwoliłem jej ruszyć. Przeczytałem jednozdaniowy opis tego, co miała zrobić, i założyłem, że opisuje to, co zrobiła. Nie opisywał.
Naprawę zacząłem od jednego pytania: co się zmieniło i gdzie. Porównałem działającą stronę z ostatnim commitem sprzed instrukcji „ogranicz blog" i odpowiedź była natychmiastowa i jednoznaczna: główna konfiguracja języków, folder z treścią strony głównej i dwadzieścia sześć plików z tekstami dla poszczególnych języków, żaden z nich nawet w pobliżu katalogu bloga. Git miał każdy z tych plików dokładnie taki, jaki był wcześniej. Nic tak naprawdę nie zginęło, tylko zostało nadpisane wdrożeniem.
Przywróciłem stronę główną, CV i napisy nawigacyjne dla wszystkich trzydziestu języków z tej historii, a folder bloga zostawiłem dokładnie tak okrojony, jak chciałem: cztery języki, celowo. Została jedna luźna nitka. Link „Blog" w nawigacji dla przywróconego języka prowadził do wydania bloga w tym języku, którego już nie ma. Duplikowanie czterech wpisów do dwudziestu sześciu kolejnych języków tylko po to, żeby wypełnić ten jeden link, nie było warte zachodu, więc ustawiłem w szablonie przekierowanie na blog angielski i tak to zostawiłem.

Co następnym razem sprawdzę inaczej
Zanim teraz pozwolę jakiejkolwiek automatycznej zmianie dotknąć działającej, wielosekcyjnej strony, zadaję sobie na głos jedno dodatkowe pytanie: nazwij dokładne pliki, których to dotknie, nie funkcję, którą ma naprawić. Jeśli odpowiedź jest wymijająca, to sygnał, żeby się zatrzymać i sprawdzić, a nie uruchomić i zobaczyć, co będzie. I zanim cokolwiek zostanie skasowane, chcę mieć przed sobą rzeczywistą listę plików, a nie jednozdaniowe streszczenie tego, co instrukcja rzekomo miała znaczyć. Słowo określające zakres w instrukcji, „blog", „ten zespół", „tylko frontend", nie jest automatycznie tym samym co zakres zmiany, którą ta instrukcja wywołuje, a oba pokrywają się tylko wtedy, gdy ktoś faktycznie to sprawdził: i to jest właśnie pytanie, które odbijam do ciebie. Jaka jest najmniejsza, najpewniej ograniczona instrukcja, którą ostatnio wydałeś, a której nigdy nie zestawiłeś z tym, czego faktycznie dotknęła?
Need something like this for your own business? See how I can help →
Get the AI Audit Kickoff Checklist
Fifteen questions to ask about your own processes before you spend a cent on AI. The same first hour I run in a real audit, as a one-page PDF. Drop your email and you get it right away, plus the occasional note when I write something worth your time. No spam, unsubscribe in one click.