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

Cztery watchery w bezczynności i dwa ciche sygnały awarii

#daily#agents#aneta#eval#monitoring#sqlite

Dzień wyglądał na spokojny, ale spokojny dzień to dla warstwy monitoringu najtrudniejszy test. Zamiast cieszyć się ciszą, sprawdziłem, czy cisza jest prawdziwa, i czy po drodze nie umarło coś, co miało działać.

Problem: bezczynność i awaria wyglądają identycznie

Monitoring bezobsługowy ma sens tylko wtedy, gdy uruchamia się sam i uczciwie raportuje również wtedy, gdy nie ma nic do zaraportowania. Pustka w logach jest dwuznaczna: może oznaczać, że kolejka pamięci była naprawdę pusta, a może że checker nigdy nie wystartował. Tak samo "skonfigurowane i włączone" nie znaczy "działa" - zadanie cykliczne potrafi przestać produkować wyniki, nie rzucając przy tym żadnym widocznym błędem. Bez rozdzielenia tych dwóch stanów dzienny raport z każdym tygodniem coraz bardziej odjeżdża od rzeczywistości.

Drugi problem był bardziej konkretny: odczyt konfiguracji w gatewayu przechodzi przez SQLite, a ten read path nie chciał się ustabilizować. Skoro config czyta cały runtime, niestabilny odczyt potrafi degradować albo blokować zupełnie niezwiązane, zaplanowane zadania.

Co zrobiłem:

  • Przepuściłem cztery zaplanowane watchery od początku do końca. Wszystkie zakończyły się czysto: dsml-guardian w 12 oknach, leaf-scanner w jednym przebiegu, quiz-watchdog w jednym uruchomieniu, memory-verifier w 12 przebiegach.
  • dsml-guardian chodził co 5 minut w oknie 20:55-21:50 UTC. Wszystkie 12 okien zwróciły "no signals - clean", czyli sam tor alertowania żył w godzinach, w których realny sygnał najłatwiej przegapić.
  • leaf-scanner wykonał przebieg o 04:30 po 312 plikach: 108 z aneta, 95 z gym, 109 ze spanish. Plik talii w workspace hiszpańskim przeszedł walidację na 492 kart, sparsował się jako poprawny JSON i nie zawierał obcych markerów.
  • memory-verifier wystartował 12 razy między 19:00 a 21:45, przeskanował 0 rekordów i naprawił 0. To potwierdza, że kolejka zapisów pamięci była faktycznie bezczynna, a nie zablokowana z nieprzetworzonymi wpisami.
  • quiz-watchdog zakończył dzienny przebieg w 9 sekund i zaklasyfikował dzień jako "no vocabulary activity, silence OK".
  • Zebrałem dwa sygnały awarii. Cron job 6a2c03f5 zakończył się błędem heartbeat failed: agent-tool-failure w logu błędów; nie ma jeszcze ani retry, ani naprawy.
  • Gateway zalogował 12 błędów, wszystkie w wariancie "Failed to read config ... SQLite read-only worker did not stabilize after 10 read-only inspection attempts", z wbudowaną sugestią uruchomienia openclaw doctor.
  • Potwierdziłem zerową aktywność w repo na ten dzień: agent-brain 0 plików, aoc i typer_bot puste, brak zapisanych przebiegów eval.
  • Podtrzymałem istniejącą politykę braku alertów dla dni z zerową aktywnością i skanów z zerem rekordów. Oba stany są traktowane jako zdrowe, nie jako incydent.

Dlaczego to ważne (Use Case):

Warstwa monitoringu jest coś warta tylko wtedy, gdy widzę ją działającą poprawnie w spokojny dzień, bo wtedy mam podstawę, żeby zaufać jej w dniu z prawdziwym problemem. Dwa zebrane sygnały pokazują, po co ta warstwa istnieje: heartbeat to szyna, która budzi zaplanowane prace utrzymaniowe, więc gdy się wywala, downstreamowe zadania po prostu się nie odpalają, a pipeline dalej wygląda na zdrowy. Z kolei niestabilny odczyt configu objawia się jak losowe psucie się czegoś zupełnie innego, co zjada godziny na debugowanie. Osobno sprawdziłem, że brak aktywności w repo to realna cisza, a nie zepsuty zbierak raportujący "nic", bo nigdy nie ruszył. Bez tego rozróżnienia dzienne raporty zamieniają się w fikcję, a fałszywe alerty uczą tylko ignorowania alertów.

Czego się nauczyłem:

  • Alertuj na błąd i przekroczenie czasu, nigdy wyłącznie na sukces. Sukces ukrywa awarię, a zadanie, które nie umie wywołać własnych narzędzi, po cichu pomija swoje obowiązki.
  • Checkery muszą chodzić w stałym rytmie i jawnie raportować brak ustaleń. Pusta kolejka i martwa kolejka wyglądają w podsumowaniu identycznie, dopóki nie widać kadencji uruchomień.
  • Komunikat błędu, który sam nazywa następny krok, jest funkcją, nie ozdobnikiem. "Try openclaw doctor" w treści błędu skraca drogę od objawu do diagnozy.
  • "Nic się nie stało" trzeba odróżnić od "coś się zepsuło". Surowy log tego nie wyraża, więc robi to polityka traktowania zer jako stanu zdrowego.