---
okf: "0.1"
type: session-log
visibility: private
status: active
updated: 2026-06-30
links: []
---

# Sesja 2026-06-30 — fleet-prometheus liveness: reguły NodeDown + wpięcie watchdog→Prometheus

## Cel

Kontynuacja "Prometheus jako źródło prawdy liveness floty" (kroki 4 i 5 z planu
w backlogu): reguły alertowe liveness + drugie wejście brain-watchdoga z Prometheusa.

---

## ZROBIONE

### feat(fleet-prometheus): reguły liveness NodeDown (commit `d417000`)

Dodano `rules/liveness.yml` z regułą `NodeDown`:

```yaml
- alert: NodeDown
  expr: up{node=~"vps|piha"} == 0
  for: 5m
  labels:
    severity: critical
```

**Decyzja projektowa**: tylko `vps` i `piha` w masce — oba always-on (serwer, infra).
`solaria` i `lustro` świadomie wykluczone: intermittent, mają własny wzorzec offline.
Będą w anomaly detection gdy uzbiera się historia metryk (~2-4 tyg). Alertmanager
celowo pominięty — brak instancji, alerty idą przez brain-watchdog.

**Trzy miejsca wymagające spójności** (pułapka z tym composem):
1. `rules/liveness.yml` — sama reguła
2. `docker-compose.yml` — mount `./rules:/etc/prometheus/rules:ro`
3. `prometheus.yml` — `rule_files: ["rules/*.yml"]` (odkomentowane)

Deploy: `deploy.sh vps` OK (fix A `3b71707` ponownie potwierdzony — `Skipping
control-plane`). fleet-prometheus Recreated (zmiana compose wymusiła recreate —
reguły weszły). Weryfikacja: `NodeDown state=inactive`, `/api/v1/alerts` = `[]`.
Poprawnie — vps i piha są UP, reguła uzbrojona i cicha.

---

### feat(brain-watchdog): poll Prometheus /api/v1/alerts → Telegram (commit `62d6fc0`)

Drugie źródło alertów w brain-watchdog: poll `/api/v1/alerts` (firing) → Telegram.

**Architektura A — dwa niezależne tory**:
- Tor mózgu (`check()` + blok `main()`) — **NIETKNIĘTY**. 7 starych testów mózgu pass.
- Tor Prometheusa (`check_prometheus_alerts()`, debounce per-alert, oddzielny klucz
  w `state.json`) — niezależny, nie interferuje z torem mózgu.

**Debounce**: klucz `alertname:node` w `state.json` (pole `prom_alerted`). Przy firing
wysyła Telegram raz; milczy dopóki alert trwa; wysyła recovery gdy alert znika.
Nie spamuje co tick.

**Opcjonalność**: `PROMETHEUS_URL` opcjonalny w `.env`. Pusty = Prometheus polling
wyłączony, graceful fallback (wzorzec jak `HEALTHCHECKS_URL`).

**Testy**: 12 testów pass (7 mózg + 5 Prometheus — nowe: disable when empty URL,
single alert sent once, recovery sent, no spam between ticks, no crash on HTTP error).

**Deploy na PIHA** (nie VPS — watchdog tam żyje):
- `docker compose up -d --build --force-recreate`
- `PROMETHEUS_URL=http://100.95.58.48:9090` dodany do `/opt/homelab/config/brain-watchdog/.env`
- Kontener Started, ping mózgu OK, brak błędów polla w logach

---

## INCYDENT: PIHA divergent branches (rozwiązane)

PIHA przed deployem siedział na `origin/task/kb-gmail-import` (4 commity KB:
`3461dea`/`c5dd8f3`/`f0e4d90`/`57a27af`) zamiast na `master`. Przyczyna: poprzednia
sesja KB zostawiła PIHA na branchu roboczym.

**Praca NIE zginęła** — wszystkie 4 commity KB są na `origin/task/kb-gmail-import`
(zweryfikowane `git branch -r --contains <hash>` PRZED jakimkolwiek resetem).

Bezpieczny `git reset --hard origin/master` (working tree był czysty, robota na
origin). PIHA wrócił na `master` (`62d6fc0`), deploy watchdoga ponowiony OK.

**Reguła na przyszłość**: PIHA deploy-only na `master`. Po deployu/teście zawsze
wrócić: `git checkout master && git pull`. Nie zostawiać noda na branchu roboczym.

---

## PENDING (NIE potwierdzone — nie zakładać sukcesu)

- **Aktywność polla Prometheus w brain-watchdog** nie jest widoczna w logach startowych
  (log startu pokazuje zmienne mózgu, nie `PROMETHEUS_URL`). Wnioskujemy że poll działa
  (brak błędów, `.env` ma URL, 5 testów pass), ale pełne potwierdzenie end-to-end
  przyjdzie przy pierwszym realnym firing: `NodeDown` fires → watchdog łapie →
  Telegram. Alternatywnie: dorzucić log polla przy starcie (drobny follow-up).

---

## Wnioski

- **Pętla liveness PRAWIE zamknięta**: Prometheus wykrywa (reguła NodeDown, inactive=OK)
  → watchdog czyta firing → Telegram. Brakuje tylko realnego testu end-to-end, który
  przyjdzie przy pierwszej realnej awarii always-on węzła (jak tor mózgu w boju wczoraj).

- **verify-before-reset uratował pracę KB**: `git branch -r --contains` przed `reset
  --hard` potwierdził że commity są na origin — reset był bezpieczny. Wzorzec do
  powielenia zawsze przed reset na cudzym worktree/nodzie.

- **Architektura A (dwa niezależne tory) poprawna**: żadna zmiana toru Prometheusa
  nie mogła zepsuć toru mózgu — izolacja bez wspólnego state, nowe testy tylko dla
  nowej ścieżki. 7 starych testów mózgu pass bez zmian.

- **Następne (osobne taski)**: cutover ze starej rury eventowej (gdy liveness
  udowodniony w boju); `docker rm` ghostów B na VPS; zbadać chelsty `node_exporter`
  DOWN; supervisor bez akcji (C); anomaly detection za ~2-4 tyg.
