Stary program w Pascalu przepisany przez agenta. Cała rozmowa na stole.
Dwie minuty filmu i pełny zapis tego, co się wydarzyło: każde polecenie wydane agentowi, każde jego pytanie i każda odpowiedź. Dla programistów, którzy znają Pascala, Clippera czy Delphi lepiej niż modele językowe i chcą zobaczyć, jak dziś przenosi się taki program na nową technologię.
Autor: Tomek Wojciechowski · Ostatnia aktualizacja:
Film: dwie minuty, bez lektora.
Fragmenty mało istotne są przewinięte, a przyspieszenie widać w rogu ekranu. Ważne momenty są zatrzymane, powiększone i podpisane. Kliknij rozdział, żeby przeskoczyć.
Co na tym filmie jest prawdziwe, a co przygotowane
- Stary program powstał na potrzeby filmu. MAGAZYN 2.1 to prawdziwy, działający program w Pascalu z bazą SQLite, napisany w stylu systemów z lat 90. Hurtownia ELKOM i jej dane są zmyślone.
- Praca agenta jest prawdziwa i nagrana w całości. Około trzech godzin terminala skróconych do dwóch minut. Niczego nie wycięliśmy z kolejności zdarzeń.
- Decyzje człowieka zostały oddane agentowi. Stąd dopiski „decyzje deleguję tobie, nie pytaj” w poleceniach. Tak się nagrywa film, a nie prowadzi projekt. U siebie odpowiadasz na te pytania sam.
- Modele zmieniały się po drodze. Zaczęliśmy na najmocniejszym, limit kończył się za szybko, przeszliśmy na tańsze. Widać to w pasku stanu na dole terminala.
- Pierwsza weryfikacja nie przeszła. Pokazujemy to, bo to najważniejsza minuta całej operacji.
Zanim przeczytasz rozmowę: pięć rzeczy, które zmieniają obraz.
- Agent nie tłumaczy kodu linia po linii To nie jest konwerter
- Najpierw wyciąga ze starego kodu, co program ma robić (reguły), potem pisze nowy kod od zera w stylu nowego języka. Stary kod jest wzorcem zachowania, a nie tekstem do przekładu.
- Stary kod jest tylko do odczytu Jedna linia w ustawieniach
- Reguła
"deny": ["Edit(/legacy/**)"]w.claude/settings.jsonsprawia, że agent nie może zmienić ani jednego znaku w starym programie. Może go tylko czytać, kompilować i uruchamiać. - Wzorcem jest stara binarka Nie dokumentacja i nie pamięć ludzi
- Stary program kompilujemy i uruchamiamy na kopii bazy. Co wypisze, to jest prawdą. Nowy program ma wypisać to samo, znak w znak.
- Stan pracy leży w plikach Nie w rozmowie
- Katalog
analysis/trzyma ocenę, reguły, plan i dowody. Dlatego można przerwać sesję, zmienić model albo oddać pracę koledze, a następne polecenie ruszy od właściwego miejsca. - Werdykt wydaje skrypt Model nie ocenia sam siebie
- O tym, czy moduł jest udowodniony, decyduje skrypt w Pythonie liczący testy i porównania. Agent może go uruchomić, ale nie może go przekonać.
Cała rozmowa z agentem, po kolei.
Osiem etapów. W każdym widać, kto mówi: co wpisał człowiek, o co zapytał agent, jaka padła odpowiedź i co agent oddał. Człowiek wpisał 17 poleceń i odpowiedział na 18 pytań. Pisownia poleceń oryginalna, bez polskich znaków tam, gdzie tak wpisano.
-
Etap 1 z 8 Start: co robimy i co ma zostać prawdą
Fable 5.2Po co ten etap. Bez zapisanego celu każdy następny krok zgadywałby, co ma powstać. Agent nie zaczyna od kodu, tylko od pytań. Odpowiedzi trafiają do pliku INTENT.md, który czytają wszystkie kolejne polecenia.
- Człowiek wpisuje
/code-modernization:modernize magazyn --source stary-system - Agent pyta
Co chcesz zrobić ze starym systemem MAGAZYN (Pascal + SQLite, ok. 890 linii)?
- Najpierw zrozumieć
- Wybrano: Przepisać na inną technologię
- Zbudować od zera
- Nowsza wersja tej samej technologii
- Agent pyta
Co musi pozostać prawdą podczas modernizacji systemu MAGAZYN?
- Wybrano: Stary system działa dalej
- Wybrano: Zachowanie identyczne
- Naprawiamy znane błędy
- Najpierw przegląd bezpieczeństwa
- Agent pyta
Czym ma się stać MAGAZYN (dziś: konsolowa aplikacja w Pascalu z bazą SQLite)?
- TypeScript (Node.js) + SQLite
- Python + SQLite
- Go + SQLite
- C# (.NET 10) + SQLite
Żadna opcja nie została wybrana. Człowiek wpisał odpowiedź własnymi słowami, w następnej turze.
- Człowiek odpowiada
TypeScript na Node.js z wbudowanym node:sqlite, ta sama baza SQLite. Raporty i import z wiersza polecen zgodne ze starym programem co do znaku, a zamiast ekranu tekstowego nowy interfejs w przegladarceOdpowiedź wpisana własnymi słowami zamiast wyboru z listy. To zdanie jest definicją sukcesu całej operacji.
- Agent oddaje
Zapisał odpowiedzi w analysis/magazyn/INTENT.md i zaproponował pierwszy krok.
- Agent pyta
Czy uruchomić teraz pierwszy krok: /code-modernization:modernize-preflight magazyn "TypeScript na Node.js z node:sqlite" --source stary-system?
- Wybrano: Tak, uruchom
- Nie teraz
- Człowiek wpisuje
-
Etap 2 z 8 Sprawdzenie środowiska i pięć pytań, na które odpowie tylko człowiek
Fable 5.2Po co ten etap. Żeby porównać stary program z nowym, oba muszą dać się uruchomić na tej samej maszynie. A o tym, co jest poza zakresem i czego nie wolno ruszyć, kod nie mówi nic. Lepiej ustalić to teraz niż w połowie pracy.
- Agent pracuje
Kompiluje próbnie stary program, sprawdza kompilator Pascala, Node i TypeScript, sprawdza regułę chroniącą stary kod przed edycją.
- Agent prosi o zgodę
Chce założyć dowiązanie legacy/magazyn do katalogu ze starym kodem. Reguła ochronna mu tego zabrania.
Człowiek założył dowiązanie ręcznie: ln -s ../stary-system legacy/magazyn
- Agent pyta
Czy kod w stary-system to cały system MAGAZYN, czy wycinek czegoś większego (coś spoza niego korzysta z jego kodu lub bazy)?
- Wybrano: Cały system
- Wycinek większej całości
- Nie wiem
- Agent pyta
Czy na tym komputerze da się zbudować i uruchomić stary MAGAZYN oraz jego testy?
- Wybrano: Tak, buduje się lokalnie
- Tak, są też testy/CI
- Nie da się
- Nie wiem
- Agent pyta
Czy MAGAZYN ma jakąś nietypową, firmową maszynerię budowania lub zależności, której nowa osoba by się nie domyśliła?
- Wybrano: Nie, tylko fpc
- Tak
- Nie wiem
- Agent pyta
Czy ktoś już wcześniej próbował modernizować MAGAZYN? Co poszło nie tak?
- Wybrano: Nie było prób
- Były próby
- Nie wiem
- Agent pyta
Czy w starym systemie MAGAZYN jest coś, czego w tym podejściu nie wolno zmieniać (np. schemat bazy, format pliku importu z kolektora, układ raportów)?
- Nic szczególnego
- Wybrano: Baza i formaty plików
- Nie wiem
- Agent oddaje
PREFLIGHT.md: środowisko gotowe, stary program się buduje, stos docelowy działa. Podaje następne polecenie.
- Agent pracuje
-
Etap 3 z 8 Ocena i mapa: co właściwie dostaliśmy
Fable 5.2Po co ten etap. Tu wychodzą błędy, o których „nikt nie wiedział”, i kolejność przepisywania: najpierw moduły, od których zależą inne, na końcu ekran.
- Człowiek wpisuje
/code-modernization:modernize-assess magazyn - Agent pracuje
Trzech agentów czyta kod niezależnie: struktura, dług techniczny, bezpieczeństwo. Programu jeszcze nie uruchamia.
- Agent oddaje
ASSESSMENT.md: inwentarz, lista ustaleń (m.in. wstrzyknięcie SQL, dublowanie importu, przepełnienie kwot) i zalecana droga.
- Człowiek wpisuje
/code-modernization:modernize-map magazyn - Agent oddaje
TOPOLOGY.html: interaktywna mapa zależności między modułami, tabel bazy i wejść do programu.
- Człowiek wpisuje
-
Etap 4 z 8 Reguły biznesowe: specyfikacja, której firma nigdy nie miała
Fable 5.2Po co ten etap. Agent wie, co kod robi, ale nie wie, czy tak miało być. Dlatego przy regułach krytycznych z podejrzeniem błędu zatrzymuje się i pyta. To miejsce, w którym człowiek znający program jest niezastąpiony.
- Człowiek wpisuje
/code-modernization:modernize-extract-rules magazyn - Agent pracuje
Uruchamia 109 agentów (ok. 2,3 mln tokenów). Każda reguła dostaje kartę z cytatem plik:linia, a drugi agent ją sprawdza.
- Agent oddaje
BUSINESS_RULES.md: 42 reguły, 10 krytycznych (P0). Osiem wymaga osądu człowieka.
- Człowiek wpisuje
/code-modernization:modernize-review magazyn - Agent pyta
RULE-001: Wszystkie kwoty to całe grosze w liczbach 32-bitowych. Podejrzenie błędu: brak ochrony przed przepełnieniem, duża ilość × cena po cichu daje błędną (nawet ujemną) kwotę.
- Wybrano: Dobrze
- Źle lub niechciane
- Nie wiem
- Agent pyta
RULE-002: Średnia ważona cena zakupu przy PZ. 6 szt. po 890 gr + 5 szt. po 865 gr → 878 gr. Podejrzenie błędu: średnia jest obcinana, a nie zaokrąglana, więc koszt powoli dryfuje w dół.
- Wybrano: Dobrze
- Źle lub niechciane
- Nie wiem
- Agent pyta
RULE-003: Cena na WZ po rabacie. 171 gr, rabat 25% → 129 gr. Podejrzenie błędu: rabat jest obcinany w dół, a marża i VAT zaokrąglane od połowy w górę.
- Wybrano: Dobrze
- Źle lub niechciane
- Nie wiem
- Agent pyta
RULE-010: WZ wymaga stanu dla każdej pozycji, wszystko albo nic. Brak jednego towaru odrzuca cały dokument.
- Wybrano: Dobrze
- Źle lub niechciane
- Nie wiem
- Agent pyta
RULE-011: Kontrola stanu jest per pozycja, nie per towar. Stan 6, dwie pozycje po 5 szt. → obie przechodzą, stan −4. Podejrzenie błędu: ujemny stan mimo zasady „wszystko albo nic”.
- Wybrano: Dobrze
- Źle lub niechciane
- Nie wiem
- Agent pyta
RULE-030: Opłata manipulacyjna 5,00 zł przy zamówieniu poniżej 50,00 zł i rabacie klienta poniżej 10%. Podejrzenie błędu: stawka VAT opłaty wpisana na sztywno.
- Wybrano: Dobrze
- Źle lub niechciane
- Nie wiem
- Agent pyta
RULE-031: Rabat = stały rabat klienta + 5 punktów za ilość, zero na usługi, limit 25%.
- Wybrano: Dobrze
- Źle lub niechciane
- Nie wiem
- Agent pyta
RULE-032: Najwyżej 20 pozycji na dokument; import po cichu gubi nadmiar. Podejrzenie błędu: cicha utrata danych, towar z pozycji 21+ nie trafia na stan.
- Wybrano: Dobrze
- Źle lub niechciane
- Nie wiem
„Dobrze” nie znaczy tu „to nie jest błąd”. Znaczy: tak program działa dziś i tak ma działać po przenosinach. Poprawki przyjdą później, osobno.
- Człowiek wpisuje
-
Etap 5 z 8 Plan i podpis
Fable 5.2Po co ten etap. Plan to dokument dla człowieka, który bierze odpowiedzialność. Zatwierdza się go edycją pliku, a nie słowem w czacie: zostaje ślad, kto, kiedy i na jaki zakres się zgodził. Bez podpisu polecenia budujące odmawiają pracy.
- Człowiek wpisuje
/code-modernization:modernize-brief magazyn - Agent oddaje
MODERNIZATION_BRIEF.md: cel, architektura docelowa, cztery fazy z kryteriami wyjścia, dziewięć otwartych pytań (opisane niżej) i pusty blok podpisu.
- Człowiek zatwierdza
Edycja pliku MODERNIZATION_BRIEF.md: podpis w sekcji 8 („Approval covers: Full plan”), odhaczone pytania 1–9.
- Człowiek wpisuje
Zatwierdzilem plan w sekcji 8 (caly plan) i odhaczylem pytania 1-9, przyjmuje rekomendacje. /code-modernization:modernize-transform magazyn - Agent pyta
Czy zatwierdzasz plan przepisania modułu BAZA (dostęp do bazy, schemat, dane startowe i tryb INIT) na TypeScript, z dowodem przez porównanie zrzutu bazy i wyjścia ze starą binarką?
- Tak, zaczynaj
- Wybrano: Tak, bez dalszych pytań
- Nie, zmień plan
- Człowiek wpisuje
-
Etap 6 z 8 Przepisywanie: cztery moduły bez interfejsu
Opus 5.5Po co ten etap. Każdy moduł przechodzi tę samą drogę: plan modułu, testy uruchamiające starą binarkę, nowy kod, przegląd przez osobnego agenta-krytyka. Od tego miejsca pytania agenta znikają, bo w każdym poleceniu jest dopisek „nie pytaj”. U siebie tego dopisku nie dawaj.
- Człowiek wpisuje
Kontynuuj /code-modernization:modernize-transform magazyn BAZA od miejsca przerwania: implementacja juz jest, agent testow charakteryzacyjnych nie skonczyl. Oszczedzaj tokeny: najwyzej jeden subagent naraz, bez zbednego czytania od nowa. Decyzje w module deleguje tobie, nie pytaj.Sesję przerwaliśmy, bo zużycie limitu rosło za szybko, i wznowiliśmy na tańszym modelu. Stan pracy leży w plikach, więc inny model podjął ją od miejsca przerwania.
- Agent oddaje
Moduł BAZA: zrzut bazy założonej nowym kodem identyczny ze zrzutem ze starej binarki.
- Człowiek wpisuje
/code-modernization:modernize-transform magazyn RAPORTY (zatwierdzam plan z gory, decyzje deleguje tobie, nie pytaj; najwyzej jeden subagent naraz) - Agent oddaje
Moduł RAPORTY: 168 testów, 63 raporty porównane ze starą binarką bajt po bajcie, bez niezaakceptowanych różnic.
- Człowiek wpisuje
/code-modernization:modernize-transform magazyn LOGIKA (zatwierdzam plan z gory, decyzje deleguje tobie, nie pytaj; najwyzej jeden subagent naraz) - Agent oddaje
Moduł LOGIKA (dokumenty PZ i WZ, rabaty, opłata manipulacyjna): identyczny zrzut bazy po wystawieniu tych samych dokumentów przez oba programy.
- Człowiek wpisuje
/code-modernization:modernize-transform magazyn MAGAZYN (zatwierdzam plan z gory, decyzje deleguje tobie, nie pytaj; najwyzej jeden subagent naraz, subagentom dawaj model sonnet) - Agent prosi o zgodę
Prosi o zgodę na polecenie z rm -f * w katalogu tymczasowym testów.
- Wybrano: Tak
- Nie
Zgoda wydana po przeczytaniu polecenia: kasuje wyłącznie własny podkatalog roboczy.
- Agent oddaje
Moduł MAGAZYN (import i wiersz poleceń). Odtworzone dziwactwa starego kompilatora, np. ilość wpisana jako $1F jest przyjmowana jako liczba szesnastkowa.
- Człowiek wpisuje
-
Etap 7 z 8 Dowód: pierwsze podejście nie przechodzi
Opus 5.5Po co ten etap. Weryfikacja zaczyna od zera i nie ufa notatkom z budowy. Werdykt liczy skrypt. Kiedy wynik jest zły, nie negocjuje się z nim, tylko uzupełnia braki i uruchamia skrypt ponownie.
- Człowiek wpisuje
/code-modernization:modernize-verify magazyn (decyzje deleguje tobie, nie pytaj; najwyzej jeden subagent naraz, subagentom dawaj model sonnet) - Agent pracuje
Buduje starą binarkę od nowa, puszcza wszystkie testy, wstrzykuje celowe błędy (kanarki), porównuje oba programy na świeżych danych.
- Agent prosi o zgodę
Prosi o zgodę na czytanie skryptów pluginu, żeby zrozumieć, skąd wziął się werdykt.
- Tak
- Wybrano: Tak, do końca sesji
- Nie
- Agent oddaje
NOT PROVEN. Jeden moduł udowodniony, siedem pozycji do poprawy: czterem modułom brakuje testów przypisanych do reguł krytycznych, a dwa katalogi narzędziowe są oceniane jak kod produkcyjny.
- Człowiek wpisuje
Zrob oba kroki sam, bez pytania: w BAZA, MAGAZYN, RAPORTY i REGULY dopisz brakujace testy regul P0 z identyfikatorem w nazwie (albo usun bledne powiazanie), przenies scripts i test-support do katalogu uznawanego za testowy, a potem uruchom ponownie /code-modernization:modernize-verify magazyn. Najwyzej jeden subagent naraz, na modelu sonnet. - Agent oddaje
Pięć modułów PROVEN: 535 testów bez porażek, każdy kanarek wywrócił testy, 108 przypadków zgodnych ze starą binarką. Blok podpisu pod dowodem zostaje pusty.
- Człowiek wpisuje
-
Etap 8 z 8 Interfejs, bezpieczeństwo i ostatnia weryfikacja
Sonnet 5.5Po co ten etap. Interfejs nie zawiera logiki biznesowej, więc wystarcza tańszy model. Dokument wystawiony z przeglądarki ma zostawić w bazie dokładnie to samo, co ten sam dokument z importu.
- Człowiek wpisuje
/model sonnet - Człowiek wpisuje
/code-modernization:modernize-transform magazyn EKRAN (zatwierdzam plan z gory, decyzje deleguje tobie, nie pytaj; najwyzej jeden subagent naraz, na modelu sonnet. Wyglad interfejsu zbuduj na design systemie SZRON: uzyj skilla /szron26-ds, motyw grafit, bez animacji tekstu. Przegladarki nie uruchamiaj, sprawdzenie w Chrome zrobie sam.) - Agent oddaje
Moduł EKRAN: strony w przeglądarce zamiast ekranu tekstowego, serwer tylko na 127.0.0.1. Raporty pokazane jako tekst o stałej szerokości przeniesiony ze starego ekranu.
- Człowiek wpisuje
/code-modernization:modernize-harden magazyn (decyzje deleguje tobie, nie pytaj; najwyzej jeden subagent naraz, na modelu sonnet; serwera na porcie 8787 nie zatrzymuj) - Agent oddaje
Przegląd bezpieczeństwa nowego kodu i łatka zapisana do pliku. Plugin sam jej nie stosuje. Wstrzyknięcia SQL ze starego programu są w nowym zamknięte.
- Człowiek wpisuje
Zrob po kolei, bez pytania: 1) zastosuj latke security_remediation.patch i uruchom npm run check. 2) W interfejsie WWW raporty (stany, braki, kontrahenci, obroty, podglad dokumentu) pokaz jako prawdziwe tabele HTML w stylu SZRON: kolumny liczbowe do prawej, wiersz sumy wyrozniony, stan ponizej minimum i ZLY NIP jako bursztynowe oznaczenie w osobnej kolumnie, polskie znaki w naglowkach, strona na pelna szerokosc tresci. Dane bierz z tych samych funkcji co dotad, a eksport tekstowy (Pobierz jako tekst) zostaw bajt w bajt zgodny ze starym programem. W formularzach PZ/WZ kontrahent jako lista rozwijana z nazwami, indeks z podpowiedzia (datalist z nazwa towaru i stanem). 3) Testy i npm run check. 4) /code-modernization:modernize-verify magazyn. Najwyzej jeden subagent naraz, na modelu sonnet. Serwer na porcie 8787 mozesz zrestartowac tym samym poleceniem z ta sama baza.Jedyne polecenie spoza ścieżki pluginu: poprawka po obejrzeniu wyniku. Wierne odtworzenie dotyczy liczb, a nie wyglądu.
- Agent oddaje
Sześć z sześciu modułów PROVEN: 131 przypadków bez niezaakceptowanych różnic, 7 kanarków, każdy wywrócił testy.
- Człowiek wpisuje
Jak to czytać
- Pytania kończą się po etapie 5. To skutek dopisku „nie pytaj” w poleceniach, a nie cecha narzędzia. Bez niego agent przed każdym modułem pokazuje plan i testy i czeka na zgodę.
- Wszystkie osiem reguł dostało „Dobrze”. Na filmie nikt nie znał tego magazynu od dwudziestu lat, więc przyjęliśmy zasadę: odtwarzamy wszystko, jak jest. U siebie część odpowiedzi brzmiałaby „Źle” albo „Nie wiem” i trafiłaby do planu jako pytanie do rozstrzygnięcia.
- Ani jednej linii kodu napisanej ręcznie. Człowiek nie dotknął nowego programu. Wpisywał polecenia, odpowiadał i zatwierdzał.
Ta sama reguła w trzech postaciach.
Opłata manipulacyjna dopisana w 1999 roku na prośbę księgowej. W starym kodzie to komentarz i sześć linii. Agent zrobił z niej kartę reguły, a dopiero z karty nowy kod.
{ 12.03.99 - na prosbe p. Krysi: male zamowienia ponizej 50 zl }
{ dostaja oplate manipulacyjna 5 zl. Nie dotyczy stalych klientow }
{ (rabat od 10%). NIE RUSZAC - ksiegowosc na tym stoi. }
RabKontr := JednaLiczba('SELECT rabat FROM kontrah WHERE id='
+ IntToStr(KontrId));
if (DokNetto < 5000) and (RabKontr < 10) then
begin
ZapiszPozycje(DokId, 0, 'Oplata manipulacyjna', 1, 500, 23);
DokNetto := DokNetto + 500;
DokVat := DokVat + Procent(500, 23);
end;### RULE-030: Small-order handling fee on goods issues
Priority: P0
Source: LOGIKA.PAS:207-216
Given A customer with 0% discount buying 10 m of UTP-5E
at 1.23 zl (net 12.30 zl)
When The WZ is posted
Then A line 'Oplata manipulacyjna' 1 x 5.00 zl at 23% VAT
is added; document net is 17.30 zl and VAT is 3.98 zl
Edge cases: Net exactly 50.00 zl: no fee;
Customer with discount exactly 10%: no fee; ...
Suspected defect: Fee VAT rate is hardcoded rather than
configurable. Source comment (dated 12.03.99) says
accounting depends on this rule as is.
Confidence: Highconst PROG_OPLATY_GR = 5000;
const OPLATA_GR = 500;
const VAT_OPLATY = 23;
// ...
// 12.03.99: zamowienia ponizej 50 zl netto dostaja 5 zl oplaty;
// nie dotyczy stalych klientow (rabat od 10%).
// Liczy sie staly rabat klienta, nie rabat ilosciowy.
// "NIE RUSZAC - ksiegowosc na tym stoi."
const rabatKlienta = baza.jednaLiczba(
'SELECT rabat FROM kontrah WHERE id = ?', kontrahentId);
if (sumy.netto < PROG_OPLATY_GR
&& rabatKlienta < RABAT_STALEGO_KLIENTA) {
zapiszPozycje(baza, dokId, 0, 'Oplata manipulacyjna',
1, OPLATA_GR, VAT_OPLATY);
dodajPozycje(sumy, OPLATA_GR, VAT_OPLATY);
}- Zapytanie z parametrem. W starym kodzie numer kontrahenta jest doklejany do tekstu zapytania. W nowym idzie jako parametr
?, więc nie da się nim zmienić treści zapytania. - Liczby z nazwami. 5000, 10 i 500 dostały nazwy. Wartości zostały te same.
- Arytmetyka 32-bitowa zachowana celowo. Kwoty w nowym module przechodzą przez funkcje, które zawijają wynik do 32 bitów jak
LongIntw Pascalu (longInt,iloczyn32). To decyzja z planu, pytanie nr 4. - Komentarz z 1999 roku przeszedł do nowego kodu. Razem z ostrzeżeniem, żeby nie ruszać.
- Reguła została. Opłata nadal się nalicza. Zmiana reguły to osobna decyzja biznesowa, podejmowana po przenosinach.
Co agent znalazł w starym kodzie przy okazji.
Żadnego z tych błędów nie szukaliśmy. Wyszły w ocenie i przy wydobywaniu reguł, każdy z numerem linii.
- Wstrzyknięcie SQL w imporcie
- Zapytania są sklejane z tekstu. Data w pliku importu albo numer dokumentu w rodzaju " OR 1=1 -- zmienia treść zapytania.
- Dublowanie dokumentów
- Ten sam plik importu wczytany drugi raz księguje wszystko ponownie. Program nie pamięta, co już wczytał.
- Przepełnienie kwot
- Kwoty w groszach siedzą w liczbie 32-bitowej. Powyżej ok. 21 mln zł wartość zawija się na ujemną, bez komunikatu.
- Ciche ucinanie dokumentu
- Dokument z importu ma najwyżej 20 pozycji. Dwudziesta pierwsza znika bez ostrzeżenia.
- Stan poniżej zera
- Każda pozycja wydania jest sprawdzana osobno. Ten sam towar w dwóch pozycjach może sprowadzić stan poniżej zera.
- Numeracja przez liczenie
- Numer dokumentu to liczba dokumentów plus jeden. Dwa stanowiska naraz mogą dostać ten sam numer.
Wstrzyknięcia SQL nowy program zamyka, bo tak zdecydowano w planie. Pozostałe zachowania odtwarza dokładnie, łącznie z przepełnieniem i ucinaniem, i ma na to testy. Powód: po przenosinach raporty mają się zgadzać ze starymi co do grosza. Błędy poprawia się potem, po jednym, każdy jako świadoma zmiana.
Dziewięć pytań, na które odpowiada człowiek.
To jest praca, której agent nie wykona. Plan zatrzymuje się na tych pytaniach i czeka na podpis. Na filmie przyjęliśmy rekomendacje agenta. W prawdziwym projekcie odpowiada osoba, która zna ten magazyn.
| Nr | Pytanie | O co chodzi | Decyzja na filmie |
|---|---|---|---|
| 1 | Zgodność czy bezpieczeństwo? | Zapytania parametryzowane zamykają wstrzyknięcia SQL, ale zmieniają wynik dla złośliwych wejść. | Zabezpieczyć. Różnica zapisana jako zaakceptowana. |
| 2 | Katalog i wersje | Gdzie leży nowy kod i do której wersji Node jest przypięty. | modernized/magazyn, Node 25.x. |
| 3 | Komunikaty błędów bazy | Stary program przy błędzie wypisuje całe zapytanie SQL. | Zachować kod wyjścia i pierwszą linię, treść zapytania pominąć. |
| 4 | Przepełnienie 32-bitowe | Odtworzyć zawijanie kwot czy poprawić? | Odtworzyć dokładnie, żeby raporty zgadzały się ze starymi. |
| 5 | Dwa programy na jednej bazie | Czy nowy program może zapisywać w produkcyjnej bazie równolegle ze starym? | Do końca fazy 3 nowy tylko czyta. Potem księgować wolno w jednym naraz. |
| 6 | Dostęp do interfejsu | Stary program nie ma logowania. Serwer WWW w sieci poszerzyłby tę lukę. | Nasłuch tylko na 127.0.0.1, bez logowania. |
| 7 | Dziwactwa ekranu | ESC zapisuje dokument, po 12 pozycjach zapis następuje sam. | W przeglądarce jawne przyciski Zapisz i Anuluj. Różnica zaakceptowana. |
| 8 | Kartoteki | Stary program nie pozwala edytować towarów i kontrahentów. | Poza zakresem przenosin. |
| 9 | Pytania do eksperta | Dziesięć reguł niższej wagi, przy których agent nie był pewien intencji. | Odtworzyć obecne zachowanie, odpowiedzi zebrać później. |
Co jest dowodem, a czego dowód nie obejmuje.
Udowodnione
- 535 testów, 0 porażek w pierwszym pełnym pakiecie dowodowym (moduły bez interfejsu).
- 131 przypadków porównanych ze starą binarką w ostatnim pakiecie, 0 niezaakceptowanych różnic.
- 7 kanarków, czyli celowych błędów. Każdy wywrócił testy.
- 36 porównań na świeżych danych, w tym 12 scenariuszy importu, których wcześniej nikt nie widział.
- 6 zaakceptowanych różnic, każda z powodem zapisanym w planie.
Nieudowodnione (lista z raportu agenta)
- Zachowanie na wejściach, których nikt nie wypróbował.
- Szybkość, bezpieczeństwo i praca dwóch programów na jednej bazie naraz.
- Zachowanie, którego nikt nie zapisał jako reguły.
- Jakość testu: identyfikator reguły w nazwie pokazuje, że test ją wymienia, a nie że jest dobry.
- Zaakceptowana różnica to decyzja, a nie dowód.
Pod raportem zostaje pusty blok podpisu. Imię, rola, data, decyzja: przyjmuję, przyjmuję z warunkami, odrzucam. Na filmie jest pusty do końca. Udowodnione nie znaczy zatwierdzone.
Słowniczek dla starej szkoły.
Dwanaście pojęć, które padają na filmie i w poleceniach. Bez nich trudno ocenić, czy to, co widać, jest solidne.
- Agent
- Model językowy, który nie tylko odpowiada, ale sam wykonuje polecenia: czyta pliki, kompiluje, uruchamia testy, poprawia kod i sprawdza wynik. Odpowiednik programisty przy terminalu.
- Subagent
- Osobna kopia agenta uruchomiona do jednego zadania, z własną pamięcią. Tak powstaje „drugi czytelnik”: krytyk nie zna toku myślenia autora, więc łatwiej znajduje dziury.
- Prompt
- Polecenie wpisane agentowi zwykłym językiem. Polecenia zaczynające się od ukośnika to gotowe procedury z pluginu.
- Plugin
- Paczka procedur, skryptów i wyspecjalizowanych agentów doinstalowywana do Claude Code. Tu: code-modernization, oficjalna wtyczka Anthropic.
- Token
- Jednostka tekstu, którą model czyta i pisze (mniej więcej 3/4 słowa). W tokenach liczy się koszt i limity. Czytanie kodu też kosztuje.
- Test charakteryzacyjny
- Test, który nie sprawdza, czy program działa dobrze, tylko zapisuje, jak działa dziś. Uruchamia stary program, zapamiętuje wynik i wymaga tego samego od nowego.
- Porównanie bajt po bajcie
- Stary i nowy program dostają te same dane. Skrypt porównuje wyjście znak w znak, ze spacjami i końcami linii. Nie ma miejsca na „mniej więcej to samo”.
- Kanarek
- Celowo wprowadzony błąd w jednej linii nowego kodu. Jeśli testy go nie wykryją, to znaczy, że niczego nie pilnują. Tu każdy z kanarków wywrócił testy.
- Reguła P0
- Reguła biznesowa, której złamanie byłoby kosztowne albo nieodwracalne: wyliczenie ceny, stan magazynu, numeracja dokumentów.
- PROVEN
- Werdykt skryptu, nie modelu: każda reguła krytyczna ma zaliczony test, kanarki zadziałały, porównania nie mają niezaakceptowanych różnic. To dowód, a nie zatwierdzenie.
- Zaakceptowana różnica
- Miejsce, w którym nowy program celowo zachowuje się inaczej niż stary, z powodem i podpisem człowieka. Tu jest ich sześć.
- Strangler fig
- Przenosiny kawałek po kawałku: nowy kod przejmuje kolejne funkcje, a stary system działa do końca. Przeciwieństwo „wielkiego przełączenia”.
Rachunek i to, co poszło nie tak.
- Czas z nagrań terminala
- Około trzech godzin pracy agenta: 37 minut analizy i planu, reszta to przepisywanie, weryfikacje i poprawki. Jeden moduł zajmował od 13 do 31 minut.
- Koszt najdroższy krok
- Wydobycie reguł: 109 agentów i ok. 2,3 mln tokenów przy programie na 890 linii. To jednorazowy koszt specyfikacji, której firma wcześniej nie miała. Przy dużym systemie plugin pyta o zgodę przed takim przebiegiem.
- Limit skończył się w połowie błąd planowania
- Zaczęliśmy na najmocniejszym modelu i po trzech modułach trzeba było zrobić przerwę. Przepisywanie i weryfikację dokończył tańszy model, interfejs jeszcze tańszy. Wniosek: najmocniejszy model na analizę i reguły, tańsze na resztę.
- Pierwsza weryfikacja: NOT PROVEN narzędzie zadziałało
- Kod był poprawny, ale czterem modułom brakowało testów przypisanych do reguł krytycznych. Bez weryfikacji nikt by tego nie zauważył. Poprawka zajęła 10 minut.
- Interfejs za wierny poprawka po obejrzeniu
- Agent przeniósł raporty do przeglądarki jako tekst o stałej szerokości, bo „zachowanie identyczne” potraktował dosłownie. Wymagało to jednego dodatkowego polecenia. Cel trzeba opisać dokładniej, niż się wydaje.
- Skala czego ten film nie pokazuje
- To mały program. Przy systemie na pół miliona linii ten sam proces potrwa tygodnie i będzie wymagał ludzi, którzy znają firmę. Kolejność zostaje ta sama: reguły, decyzje, kod, dowód.
Jak zacząć na własnym programie.
- Zrób kopię. Kod i baza w osobnym katalogu, poza produkcją. Agent pracuje wyłącznie na kopii.
- Sprawdź, czy stary program da się skompilować i uruchomić na maszynie, na której pracuje agent. Bez tego nie będzie porównania, zostaną same testy.
- Zainstaluj plugin i załóż katalog roboczy z regułą chroniącą stary kod. Instrukcja: Plugin code-modernization. Źródła pluginu: repozytorium Anthropic.
- Zatrzymaj się po czterech poleceniach:
modernize,preflight,assess,extract-rules. Dostaniesz ocenę, listę błędów i spisane reguły biznesowe. To ma wartość nawet wtedy, gdy niczego nie przepiszesz. - Przeczytaj reguły z osobą, która zna program. Każdą podejrzaną rozstrzygnijcie razem. To jest ten moment, w którym doświadczenie starej szkoły jest niezastąpione: agent wie, co kod robi, a Ty wiesz, dlaczego.
- Przepisz jeden moduł. Najlepiej raport: jasne wejście, jasne wyjście, nic nie zapisuje. Dopiero po dowodzie na pilocie bierz następne.
Macie program, którego nikt nie chce ruszać?
Zaczynamy od jednego modułu: ocena, reguły, plan i pilot z dowodem równoważności na Waszym kodzie. Krótka rozmowa wystarczy, żeby sprawdzić, czy ma to u Was sens. Odpowiadamy w 24 h.