09 · Inżynieria
Jak zmiana trafia do produkcji.
Prace są dostarczane w numerowanych rundach; w bieżącej serii jest ich 454. Każda jest wyspecyfikowana, uzgodniona, zbudowana w całości, udowodniona i udokumentowana.
Opis platformy
Środowisko programistyczne
Prace programistyczne odbywają się na dwóch maszynach, celowo utrzymywanych jako nierówne: pełnym środowisku na stacji roboczej programisty, na której znajduje się baza danych, oraz jednorazowym kontenerze w chmurze, w którym kod jest pisany i testowany zupełnie bez bazy danych.
Stacja robocza phoenix-dev26.
- Rozwiązanie jest otwierane w Visual Studio z katalogu głównego projektu i uruchamiane pod Kestrel za pomocą profilu uruchomieniowego projektu pod adresem https://localhost:51880, z dodatkowym portem zwykłego HTTP, w środowisku Development.
- Aplikacja łączy się bezpośrednio z SQL Server. Zgodnie z rozstrzygnięciem właściciela łączy się z katalogami produkcyjnymi zamiast z odtworzoną kopią deweloperską, za pomocą ciągu połączenia przechowywanego w systemowej zmiennej środowiskowej.
- W pliku projektu istnieje identyfikator user secrets, lecz w praktyce nie jest używany; konfiguracja pochodzi ze środowiska.
- Jedna znana pułapka: widoki Razor kompilują się do tego samego zestawu co modele stron, więc gdy zmiana w pliku .cs jest widoczna, a zmiana w pliku .cshtml nie, kompilacja przyrostowa ponownie używa nieaktualnego widoku. Rozwiązaniem jest usunięcie folderów obj i bin i ponowne zbudowanie.
- Skrypty schematu są uruchamiane przez właściciela ręcznie, dla każdego katalogu, z jego własnego klienta SQL.
- Jedno polecenie, verify.cmd, buduje rozwiązanie, uruchamia cztery sondy, startuje izolowaną instancję na własnym porcie, loguje się, otwiera wszystkie szesnaście stron raportów i pobiera każdą z nich jako PDF. Jego tryb przykładowy wykonuje ten sam przebieg na danych testowych (fixtures), zupełnie bez bazy danych.
Kontener w chmurze ma .NET 8 SDK, drzewo kompilacji i żadnej bazy danych.
- Brak ciągu połączenia wybiera tryb przykładowy, w którym implementacje testowe magazynów danych finansowych, raportów, kalendarza, VAT i dokumentów odpowiadają na każde zapytanie; program uruchamiający odmawia startu, jeśli ciąg połączenia jest obecny.
- Dane testowe są zbudowane z własnych dokumentów i liczb spółki, więc test może weryfikować wyniki względem liczb, które są już na papierze.
- Przeglądarka bezgłowa (headless) steruje działającą aplikacją na potrzeby sond, zrzutów ekranu i renderowania PDF.
- Lokalny zamiennik odpowiada w miejsce punktu końcowego AI oraz źródeł notowań rynkowych i kursów walut dokładnie przygotowanymi odpowiedziami, dzięki czemu arytmetykę można udowodnić bez udziału modelu.
Bramki. Dla każdej rundy uruchamianych jest trzydzieści siedem skryptów bramek i cztery przeglądy kodu źródłowego.
- Niektóre są skanami statycznymi, które weryfikują właściwość kodu źródłowego, na przykład brak nienazwanej projekcji wewnątrz CTE albo brak długiego literału szesnastkowego w pliku konfiguracyjnym.
- Cenniejsze są te, które sterują działającą aplikacją. Najkosztowniejsza lekcja tego projektu: test, który nigdy nie uruchamia tego, co uruchamia użytkownik, nie może wykryć błędu wykonania.
- Bramki weryfikują regułę ustaloną w danej rundzie, a nie wyrażenie, które zostało wydane, i przed weryfikacją usuwają komentarze; tę poprawkę trzeba było wprowadzać czterokrotnie.
Przejście między maszynami. Pliki przechodzą przez mostek plików pulpitu według stałej procedury:
- przed pierwszą edycją w rundzie dla każdego pliku, którego runda może dotyczyć, obliczany jest skrót na dysku stacji roboczej;
- przed zatwierdzeniem te same pliki są ponownie przygotowywane i porównywane pod względem treści;
- po zatwierdzeniu po obu stronach ponownie obliczane są skróty i porównywany jest łączny skrót.
"Wydane" to stwierdzenie dotyczące dysku stacji roboczej, nigdy kontenera kompilacji.
Wdrożenie kopiuje na serwer produkcyjny dokładnie cztery elementy: cały statyczny folder WWW, zestaw aplikacji, jego symbole i plik wykonywalny. Pliki konfiguracyjne nie są kopiowane, więc ustawienia i sekrety produkcyjne przetrwają wydanie. Po skopiowaniu pula aplikacji jest odświeżana, a lista kontrolna przed publikacją czyści token kondycji i potwierdza usunięcie klasy diagnostycznej.
Jak prace są specyfikowane, budowane i dowodzone
Prace są dostarczane w numerowanych rundach. Bieżąca wersja to v31.454, co pokazuje sposób prowadzenia projektu: wiele małych, kompletnych, zweryfikowanych dostaw zamiast długich gałęzi. Runda zaczyna się od prośby właściciela, jest przekształcana w macierz rozstrzygnięć, które właściciel akceptuje lub zmienia, a następnie jest wydawana w całości. Rundę dzieli się wyłącznie z powodu prac, których nie można jeszcze wykonać, na przykład nierozstrzygniętej diagnostyki lub decyzji, którą może podjąć tylko właściciel.
Każda runda pozostawia pisemny zapis.
- Notatka rundy w dokumentacji projektu opisuje, co się zmieniło i dlaczego.
- Rejestr założeń odnotowuje każdy osąd mogący okazać się błędny: ponumerowany, oznaczony w kodzie obok wiersza, którego dotyczy, opatrzony oceną ryzyka oraz zapytaniem SQL, które by go rozstrzygnęło.
- Gdy decyzja odwraca wcześniejszą, wcześniejsze rozstrzygnięcie jest przekreślane i opatrywane adnotacją zamiast usuwania, dzięki czemu historia decyzji pozostaje czytelna.
Cztery stałe reguły określają, co można zrobić bez pytania:
- Sekrety znajdują się wyłącznie w systemowych zmiennych środowiskowych, nigdy w pliku, który może udostępnić serwer WWW, i nigdy nie są wklejane do rozmowy.
- Do projektu nie wolno dodać żadnego nowego pakietu, i dlatego implementacja Web Push, generator PDF oraz parser zaproszeń kalendarzowych są w całości napisane ręcznie.
- Żadna zmiana schematu, łącznie z nowym indeksem, nie jest wprowadzana bez zgody właściciela, a każdy skrypt jest pisany tak, aby był zabezpieczony i możliwy do ponownego uruchomienia, i jest uruchamiany przez właściciela dla każdego katalogu.
- Zaksięgowane dane księgowe nigdy nie są zmieniane w celu skompensowania problemu z prezentacją, a zapisy historyczne nigdy nie są masowo korygowane jako skutek uboczny poprawki.
Dowód ma charakter warstwowy.
- Kompilacja musi być czysta.
- Przeglądy sprawdzają kod źródłowy pod kątem znanych klas błędów.
- Bramki weryfikują reguły.
- Sondy sterują działającą aplikacją.
- Ostatecznym sprawdzeniem jest zawsze porównanie skrótów z dyskiem stacji roboczej.
Gdy środowisko izolowane czegoś nie widzi, raport to stwierdza. Najwyraźniejszym przykładem jest SQL: w kontenerze kompilacji nie jest wykonywane żadne zapytanie, więc zmiana zapytania jest dowodzona statycznie i przez inspekcję, dopóki nie zostanie uruchomiona na katalogach produkcyjnych, i raport z rundy to odnotowuje.