# Sesja 2026-06-22 — decyzja: Prometheus jako źródło prawdy dla liveness floty

## Cel

Rozstrzygnięcie architektoniczne: czym zastąpić obecną rurę wykrywania liveness
floty `node-agent → rsync/ssh → observer` (warstwa sensoryczno-transportowa będąca
przyczyną większości nawracających awarii). Plus precondition infrastrukturalny pod
nowy serwis na VPS (swap).

---

## DECYZJA: Prometheus (pull, `up{}`) zastępuje WYKRYWANIE liveness

### Co zastępujemy (warstwa sensoryczno-transportowa)

Prometheus pull + metryka `up{}` przejmuje rolę dotychczasowej rury:
- **node-agent** jako shipper eventów,
- **rsync/ssh** transport,
- pliki eventów,
- observer **prune/checkpoint**,
- egzekwowanie **TTL** liveness.

To była przyczyna większości nawracających awarii:
- `uid 1004 != 1000` — strict ownership check OpenSSH wywalał shipping,
- ślepy ssh-mount (LUSTRO, `/root/.ssh` vs `/home/homelab/.ssh`),
- bloat (~242k eventów na VPS),
- race `prune` ↔ `checkpoint` w observerze,
- `NOMINAL`-bez-TTL (martwy node pokazywany jako zdrowy).

Pull eliminuje całą warstwę push: brak kluczy, brak ownership, brak event-store
do prune'owania, brak ręcznego TTL — `up==0` przez czas `for:` jest stanem prawdy.

### Świadoma granica zakresu — co ZOSTAJE

Prometheus zastępuje **wykrywanie**, NIE cały system. Nietknięte:
- **supervisor** — remediacja (`container_restart` / `redeploy`),
- **observer / panel** `agents.okit.pl` — do przepięcia na źródło Prometheus (OTWARTE,
  największy znak zapytania przy cutoverze),
- **ha-diag-agent** — logika domenowa HA (diff `system_health`, encje `unavailable`,
  WS heartbeat) — Prometheus tego nie widzi,
- historia incydentów / lifecycle,
- out-of-band watchdog.

### BEZ Alertmanagera — świadoma decyzja

Jeden kanał Telegram (`@okitaialerts_bot`). Rolę dostarczania przejmuje **brain-watchdog**:
dochodzi mu **drugie wejście** — odpytanie Prometheus `/api/v1/alerts` — obok obecnego
pingu mózgu. Reguły alertowe z histerezą (`for:`) po stronie Prometheusa; watchdog
pozostaje cienki (odczyt `firing` + Telegram). Nie wprowadzamy osobnego Alertmanagera,
żeby nie mnożyć kanałów ani komponentu do utrzymania.

> Uwaga: ta decyzja **zastępuje** wcześniejszy szkic z sesji 2026-06-17
> (blackbox_exporter + Alertmanager). Wybrano pull `up{}` + watchdog jako tor alertu.

---

## Osobny fleet-Prometheus pod GitOps — NIE adopcja domowego instance

Stawiamy **osobny** Prometheus floty, zarządzany przez GitOps. NIE adoptujemy domowego
instance na PIHA.

Powód — domowy prom na PIHA to liability nie wart adopcji:
- LAN-only (scrape `192.168.31.x`), mija nody tylko-Tailscale (VPS, chelsty),
- poza repo (`/home/pi/monitoring/prometheus.yml`, konfigurowany ręcznie),
- bez alertingu (`alerting:` i `rule_files:` puste),
- sekrety plaintext w configu (long-lived token HAOS + bearer watchtower — do rotacji).

Adopcja = dziedziczenie liability (migracja, ekstrakcja sekretów) **plus** blast-radius
na działający monitoring bezpieczeństwa domu (crowdsec / fail2ban / haos) za znikomą
wygraną. Osobny instance izoluje flotę od domu.

## Placement: VPS

- Host: VPS (`ubuntu-4gb-hel1-1`, `100.95.58.48`).
- Out-of-band zachowane: **watchdog na PIHA pilnuje VPS z innej maszyny** — Prometheus
  na VPS nie jest sędzią własnej śmierci.
- VPS ma już `node_exporter` (role: metrics-exporter) = pierwszy target floty gotowy.

---

## ZROBIONE w tej sesji

### Swap 4 GB na VPS — precondition pod Prometheusa

- `/swapfile` aktywny i **trwały** (wpis w `/etc/fstab`).
- `vm.swappiness=10` ustawione na żywo i w `/etc/sysctl.conf`.
- **Weryfikacja**: `free -h` → `Swap: 4.0Gi (0B used)`; `/proc/swaps` zawiera `/swapfile`.
- Powód: VPS ma 3.7 GB RAM, wcześniej `swap=0` — przyczyna OOM 2026-06-01. Prometheus
  jest RAM-głodny; swap to bufor bezpieczeństwa.
- ⚠️ To **host-level one-off** — nie czysto GitOps-owalne, wykonane świadomie gotowcem.
  Zapisane jako celowy host-state w `hosts/vps/host.yaml`, żeby przy odtwarzaniu VPS
  nie zniknęło cicho (wzorzec jak uid/grupy po 8-dniowej awarii).

---

## Plan następnych kroków (OTWARTE — NIE realizowane w tej sesji)

Kolejność = priorytet:

1. **Scaffold serwisu `fleet-prometheus` pod GitOps** — worktree `task/fleet-prometheus`,
   wzorzec `services/vikunja/`: `docker-compose.yml` + `env.example` + `service.yaml` +
   `README.md` + `healthcheck.sh`. Rejestracja w `hosts/vps/services.yaml` +
   `inventory/topology.yaml`. Exposure: `tailscale-internal`. Pusty scrape na start
   (self + lokalny `node_exporter` VPS).
2. **Inwentaryzacja nodów floty `100.x`** do scrape (osobny krok).
3. **Container-layer exporter** (cAdvisor lub lekki docker-state) — brakujący klocek;
   `node_exporter` nie widzi kontenerów.
4. **Reguły liveness** (`up==0 for: 5m`) w Prometheusie.
5. **brain-watchdog: drugie wejście** — odpyt Prometheus `firing` → Telegram, bez
   ruszania działającego toru `token → chat_id`.
6. **Rotacja tokenu HAOS** w domowym prom (plaintext).
7. **Przepięcie observer / panel `agents.okit.pl`** na Prometheus jako źródło —
   największy znak zapytania przy cutoverze.
8. **Parallel-run** obok rury eventowej; **cutover dopiero** gdy Prometheus-truth się
   udowodni.

---

## Wnioski

- Klasa awarii (push shipping: klucze, ownership, bloat, race, TTL) znika nie przez
  kolejny fix, lecz przez zmianę modelu transportu na **pull** — Prometheus widzi
  martwy target jako `up==0`, bez warstwy dostarczania do zepsucia.
- Granica zakresu trzymana świadomie: Prometheus = **wykrywanie**, nie remediacja ani
  logika domenowa HA. Zastępujemy sensor, nie mózg.
- Osobny instance > adopcja: nie dziedziczy się liability ani blast-radius na monitoring
  bezpieczeństwa domu dla wygody współdzielenia.
- BEZ Alertmanagera: cienki watchdog z drugim wejściem zamiast nowego komponentu —
  jeden kanał Telegram pozostaje jeden.
- Swap = precondition, nie cel — odblokowuje RAM-ciasny VPS pod nowy serwis;
  udokumentowany jako celowy host-state, nie ukryta ręczna zmiana.
