diff --git a/docs/backlog.md b/docs/backlog.md index 89401be..8e2d717 100644 --- a/docs/backlog.md +++ b/docs/backlog.md @@ -37,32 +37,51 @@ historia incydentów, out-of-band watchdog. ## Aktywne -### Rozjazd stanu Docker Compose na VPS — serwisy poza GitOps project-name +### 🔴 KRYTYCZNY — `deploy.sh vps` niszczy control-plane (project-name divergence) -**Data**: 2026-06-24 -**Źródło**: sesja 2026-06-24 (`docs/sessions/2026-06-24.md`) -**Problem**: `node-agent`, `control-plane` i inne serwisy VPS zostały utworzone inną -ścieżką / `project-name` niż widzi `deploy-node.sh` (bo VPS nigdy nie deployował się -tą ścieżką przed hostname-fixem z `ae739b5`). Przy próbie Recreate pada: -`Error: No such container: _node-agent`. `set -e` przerywa całą pętlę. -**⚠️ Dotyka żywego control-plane (~7 dni uptime) — ostrożnie, osobna sesja.** -**Fix**: uspójnić `project-name` — recreate z czystymi labelami Compose albo migracja -do jednego `--project-name` dla całego `deploy-node.sh`. +**Data**: 2026-06-24 (wykryte), 2026-06-25 (incydent potwierdzony w produkcji) +**Źródło**: sesja 2026-06-24 + sesja 2026-06-25 (`docs/sessions/2026-06-25.md`) +**Problem A — deploy.sh vps niszczy mózg**: `control-plane` jest w `hosts/vps/services.yaml` +jako zwykły serwis pętli `deploy-node.sh`. Pętla używa innego `COMPOSE_PROJECT_NAME` niż +`deploy-local.sh` (który ma `cwd=services/control-plane`). Niezgodność → Recreate → +`No such container: _control-plane-observer` → `set -e` przerywa pętlę → +observer/supervisor/executor/ui znikają. **Każdy `deploy.sh vps` rozkłada mózg.** +**Problem B — ghost kontenery w panelu**: martwe kontenery ze starych project-name'ów +(`8547b46c0317_control-plane-supervisor`, `12bd3059a70f_control-plane-observer` itp.) +są raportowane przez observera jako `error` → `System Status ERROR` w panelu mimo +zdrowego realnego mózgu. +**Incydent 2026-06-25**: mózg VPS zniknął, odtworzony ręcznie: +`ssh -t vps 'cd ~/homelab-codex-ws && git pull && cd services/control-plane && bash deploy-local.sh'` +**⚠️ NIE uruchamiać `deploy.sh vps` do czasu fixu — używać `deploy.sh control-plane` +lub `deploy-local.sh` bezpośrednio.** +**Fix**: usunąć `control-plane` z pętli `hosts/vps/services.yaml` ALBO dodać skip +w `deploy-node.sh` dla serwisów z własnym `deploy-local.sh`; potem `docker rm` ghostów. --- -### Flaky testy control-plane — state-leak w pytest (gate nierzetelny) +### Supervisor nie enqueue'uje akcji remediacji przy `error`-state -**Data**: 2026-06-24 -**Źródło**: sesja 2026-06-24 (`docs/sessions/2026-06-24.md`) -**Problem**: `test_incident_lifecycle.py::test_run_once_quarantines_bad_event` i -`::test_run_once_skips_observer_emitted_events` failują przez state-leak między -przebiegami pytest. Moduł-level stałe `EVENTS_DIR` / `FAILED_EVENTS_DIR` / checkpoint -wskazują poza `tmp_path` testu — asercje porównują ścieżki z różnych `pytest-N` runs. -Kod observera zdrowy (quarantine i checkpoint działają poprawnie). Gate deploy.sh -czerwony przy zdrowym kodzie → zmuszeni do `--no-gate`. -**Fix**: zmockować ścieżki na `tmp_path` przez fixture w testach observera. -**Skutek bieżący**: gate nierzetelny — każde `--no-gate` musi być odnotowane. +**Data**: 2026-06-25 (powtórka sygnału z 2026-06-19) +**Źródło**: sesja 2026-06-25 (`docs/sessions/2026-06-25.md`) +**Problem**: Action Queue pusta mimo `System Status ERROR` widocznego w panelu. +Supervisor nie generuje `container_restart` / `redeploy` dla serwisów w stanie `error`. +Objaw zaobserwowany co najmniej dwukrotnie — wymaga izolowanego dochodzenia. +Podejrzane: supervisor może nie reagować na error-state jeśli źródłem są ghost kontenery +(błędne project-name), nie realne health-check failures. +**Fix**: zbadać osobno — sprawdzić, czy supervisor otrzymuje właściwe eventy od observera, +czy ma własną logikę de-duplifikacji blokującą enqueue. + +--- + +### Rozjazd world-state observera: panel pokazuje serwis NOMINAL przed jego istnieniem + +**Data**: 2026-06-25 +**Źródło**: sesja 2026-06-25 (`docs/sessions/2026-06-25.md`) +**Problem**: panel wykazał `fleet-prometheus` jako nominal na SOLARII zanim kontener +w ogóle istniał — observer `world_state` rozjechany z dockerem. Artefakt rejestracji +w manifeście bez realnego kontenera. Podobna klasa błędu jak ghost kontenery. +**Fix**: observer powinien weryfikować faktyczny stan kontenera przy budowaniu world_state +zamiast opierać się wyłącznie na zarejestrowanych serwisach. --- @@ -173,6 +192,32 @@ Długoterminowo: `agent.sh new` powinien odmawiać jeśli żądana gałąź jest ## Zamknięte +### Flaky testy control-plane — state-leak w pytest — NAPRAWIONE (commit `992ff7c`) + +**Data**: 2026-06-24 (zgłoszone), 2026-06-25 (naprawione) +**Źródło**: sesja 2026-06-24 + sesja 2026-06-25 (`docs/sessions/2026-06-25.md`) +**Było**: `test_incident_lifecycle.py` flaky przez state-leak — `OBSERVER_STATE_FILE` +wyprowadzany przy imporcie, helpery patchowały `STATE_DIR` ale nie `OBSERVER_STATE_FILE` → +checkpointy pisane na realny dysk `/opt/homelab/state/` z ścieżkami otagowanymi numerem +przebiegu pytest. Gate deploy.sh czerwony przy zdrowym kodzie. +**Naprawione**: autouse monkeypatch fixture redirectujący WSZYSTKIE ścieżki stanu w tym +`OBSERVER_STATE_FILE`; usunięto buggy `_make_observer`; posprzątano zatruty realny checkpoint. +Weryfikacja: 6/6 przebiegów → 28 passed. Gate rzetelny. + +--- + +### deploy-node.sh — brak `--env-file` (bind 0.0.0.0) — NAPRAWIONE (commit `686aca7`) + +**Data**: 2026-06-25 +**Źródło**: sesja 2026-06-25 (`docs/sessions/2026-06-25.md`) +**Było**: `deploy-node.sh` nie przekazywał `--env-file` do `compose up` → zmienne `.env` +(jak `TAILSCALE_BIND_IP`) interpolowały się do pustego stringa → bind `0.0.0.0` zamiast +Tailscale IP. Potencjalna dziura na publicznym VPS. +**Naprawione**: guard `if [ -f "services//.env" ]` + `--env-file` per-serwis przed +`docker compose up`. Worktree `task/deploy-envfile-fix`, merge ff-only. + +--- + ### Swap 2–4 GB na VPS — ZROBIONE **Data**: 2026-06-22 (zgłoszone PENDING w sesji 2026-06-09 flota-recovery)