PABLO.ENGINEERING
// WRÓĆ DO WSZYSTKICH WPISÓW
// 3 min

Błędny odczyt konfiguracji kierował polecenie panelu prosto do modelu

Gdy lokalne polecenie zamiast wykonać szybką akcję w panelu wysyła pełne zapytanie do modelu LLM, użytkownik traci czas i tokeny. Właśnie tak zachowywała się wtyczka panelu po cichej zmianie w strukturze konfiguracji.

Problem: fail-closed wysyłał komendę na zewnątrz, a restarty umierały w tle

Podczas testowania panelu zauważyłem dziwne zachowanie: wpisanie komendy /portfel powinno błyskawicznie odświeżyć stan kafelków na miejscu. Zamiast tego polecenie trafiało do modelu LLM jako zwykła wiadomość czatu.

Analiza kodu ujawniła przyczynę: wtyczka próbowała odczytać konfigurację z globalnego obiektu OpenClaw zamiast z własnego węzła pluginConfig. Ponieważ lista dozwolonych użytkowników pozostawała niezdefiniowana (undefined), mechanizm obronny zadziałał w trybie fail-closed: uznał polecenie za nieautoryzowane dla wtyczki i przekazał je dalej do domyślnego brokera wiadomości.

Drugi problem dotyczył restartów serwisów: skrypt safe_admin_exec.sh przyjmował żądanie restartu w tle, ale proces roboczy ginął w momencie zamykania grupy procesów aktywnej tury (teardown grupy procesów), przez co restart po cichu nigdy nie dochodził do skutku.

Co zrobiłem: trójstopniowe rozwiązywanie konfiguracji i odłączenie sesji

  1. Przebudowałem mechanizm odczytu konfiguracji panelu na odporny potok trójstopniowy: najpierw dedykowana sekcja wtyczki, następnie ścieżka plugins.entries.<id>.config, a na końcu ustawienia płaskie jako fallback.
  2. Napisałem 5 dedykowanych testów regresyjnych sprawdzających odczyt konfiguracji we wszystkich trzech wariantach (cały zestaw 33 testów przeszedł na zielono).
  3. Do skryptu safe_admin_exec.sh dodałem wywołanie setsid, które odłącza proces restartujący od grupy procesów sesji nadrzędnej. Dzięki temu proces żyje własnym życiem i bezpiecznie kończy restart bramki nawet po natychmiastowym zamknięciu połączenia czatu.
  4. Uporządkowałem mechanizm odświeżania tokenów Google OAuth, synchronizując pliki poświadczeń w obu lokalizacjach, co wyeliminowało błędy invalid_grant pojawiające się co kilka dni przy porannych briefingach.

Dlaczego to ważne (Use Case)

Wadliwy odczyt konfiguracji z mechanizmem fail-closed przypomina inteligentny zamek do drzwi, który z powodu drobnej pomyłki w numerze mieszkania nie otwiera zamka, lecz za każdym razem dzwoni na numer alarmowy. Zamek zachowuje się bezpiecznie, ale generuje ogromny, niepotrzebny szum i koszty.

Poprawka sprawia, że komenda /portfel jest natychmiast rozpoznawana i obsługiwana lokalnie przez wtyczkę w kilka milisekund, bez marnowania tokenów i bez angażowania zewnętrznego API modelu. Z kolei dodanie setsid daje pewność, że gdy administrator zleci restart z poziomu komunikatora, bramka rzeczywiście wstanie na nowo, zamiast zamilknąć w połowie zamykania sesji.

Czego się nauczyłem

  • Mechanizm fail-closed jest doskonałym wzorcem bezpieczeństwa, ale przy błędach parsowania konfiguracji potrafi cicho przekierowywać ruch na kosztowne ścieżki rezerwowe. Zawsze należy monitorować, ile poleceń ucieka z wtyczek do modelu.
  • Asynchroniczne zadania administracyjne wywoływane z poziomu sesji muszą tworzyć nową sesję systemową (setsid). W przeciwnym razie sygnał zabicia grupy procesów sesji macierzystej zniszczy również zadanie w tle.
  • Konfiguracja wtyczek powinna być czytana deterministycznie z jawną kaskadą fallbacków, a każda zmiana formatu musi być zabezpieczona testami regresyjnymi.
#daily#openclaw#reliability#architecture