126 plikow (md, yaml, sh, py) odwolywalo sie do sciezek sprzed migracji.
15 markdown-linkow [..](..) -> policzona sciezka WZGLEDNA wobec pliku
odsylajacego (wczesniej czesc z nich byla repo-root-relative i nie
rozwiazywala sie z katalogu, w ktorym lezala)
200 odwolan tekstowych (backticki, proza, yaml, importy w kodzie)
-> nowa sciezka repo-root-relative, zgodnie z konwencja repo
5 linkow rodzenstwa (gole nazwy plikow, np. "](DEPLOY.md)") — dzialaly
tylko w starym katalogu; przeliczone recznie
Objete m.in.: CLAUDE.md (scripts/onboard/README.md -> kb/runbooks/
node-onboarding-tool.md, docs/backlog.md -> kb/phases/backlog.md),
README.md, .claude/skills/, 20 session logow, kod jobow.
Ostatnie 5 odwolan pochodzi z tresci wciagnietej rebasem z origin/master
(session log 2026-07-31, override node-agenta na SOLARII, dwie pozycje
backlogu) — wskazywaly na docs/incidents/, docs/kb/modules/ i
services/narty27/README.md sprzed migracji.
Dodany wzajemny link miedzy kb/services/control-plane.md (stub kodu)
a kb/subsystems/control-plane.md (opis, deprecated) — dwa dokumenty o tym
samym systemie, latwe do pomylenia.
Weryfikacja na 790 plikach: 0 odwolan do starych sciezek,
0 martwych linkow markdown. Lint OKF: 190/190 plikow ZGODNE.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
116 lines
5.9 KiB
Markdown
116 lines
5.9 KiB
Markdown
---
|
|
okf: "0.1"
|
|
type: session-log
|
|
visibility: private
|
|
status: active
|
|
updated: 2026-07-06
|
|
links: []
|
|
---
|
|
|
|
# Sesja 2026-07-06 — cutover liveności na Prometheus: recon starego toru + Etap 0 udowodniony w boju
|
|
|
|
## Cel
|
|
|
|
Główny projekt: Prometheus jako źródło prawdy liveności floty. Dwa kroki tej sesji:
|
|
(1) read-only recon starego toru liveności z dokładnymi punktami przełączenia
|
|
i planem etapowym; (2) Etap 0 cutoveru — bojowy dowód end-to-end toru
|
|
Prometheus → brain-watchdog → Telegram, którego brakowało od 2026-06-30.
|
|
|
|
---
|
|
|
|
## ZROBIONE
|
|
|
|
### Recon cutoveru — wmergowany (commit `d94bb38`)
|
|
|
|
Wynik: `kb/audits/prometheus-cutover-2026-07-06.md` (517 linii, read-only,
|
|
zero zmian w kodzie). Kluczowe ustalenia:
|
|
|
|
- **Cutover to podmiana klasyfikacji liveności w JEDNYM miejscu** —
|
|
`_prune_stale_world` w `scripts/observer/observer.py:312-323` + neutralizacja
|
|
event-driven flipów `:438-446` — a NIE odłączanie rury. Fizycznie nic nie znika.
|
|
- **`node_health` wozi też metryki** disk/mem/cpu do panelu i `disk_pressure`
|
|
do supervisora → rsync + eventy ZOSTAJĄ w całości.
|
|
- **Supervisor-remediacja i executor są CAŁKOWICIE niezależne od liveności węzłów**
|
|
— supervisor czyta z `nodes.json` wyłącznie `disk_pressure`. Jedyny konsument
|
|
liveności po stronie supervisora to syntetyczne eventy przejść
|
|
(`node_offline/stale/online` → alert_only → Telegram).
|
|
- **Różnica semantyk**: `up{}` mierzy "host żyje (exporter odpowiada)",
|
|
eventowy `node_health` mierzy "node-agent żyje + cały łańcuch SSH/rsync działa".
|
|
Cutover ZWĘŻA definicję liveności — padnięty node-agent przy żywym węźle zmienia
|
|
werdykt. Do świadomej akceptacji w etapie 2; rozważyć `up{job=node-agent}`.
|
|
- **chelsty-infra ma liveność WYŁĄCZNIE z eventów** (Prometheus go nie scrape'uje
|
|
po LTE) → cutover MUSI być per-węzeł (`PROM_LIVENESS_NODES`), nigdy globalny.
|
|
- **Prometheus po cutoverze = niepilnowany SPOF** (`mem_limit 512m`,
|
|
`oom_score_adj 200` — ubijalny przed control-plane) → fail-open na stary tor
|
|
obowiązkowy + watchdog na sam Prometheus (mały task przy etapie 3).
|
|
- Exportery piha/solaria/lustro istnieją **poza GitOps** (brak definicji w repo)
|
|
— rozjazd, osobny wątek.
|
|
|
|
### Etap 0 cutoveru — DONE, dowód bojowy end-to-end
|
|
|
|
Tor **Prometheus → brain-watchdog → Telegram udowodniony END-TO-END po raz
|
|
pierwszy w produkcji**. Test punktowy na VPS (celowo NIE w repo): tymczasowa
|
|
reguła `AlertTestEtap0` (`up{node="vps"}==1`, `for: 0s`) dodana do
|
|
`services/fleet-prometheus/rules/` na VPS + reload. Cztery punkty potwierdzenia:
|
|
|
|
1. **Firing w Prometheusie**: `/api/v1/alerts` → `AlertTestEtap0` firing, node vps.
|
|
2. **Watchdog spollował z PIHA**: log `[prometheus] sent alert: AlertTestEtap0:vps`
|
|
— przy okazji widoczne dwa niezależne tory (ping mózgu OK co 60 s + poll
|
|
Prometheusa osobno), zgodnie z architekturą A.
|
|
3. **Alert doleciał na Telegram** (@okitaialerts_bot): „Prometheus alert:
|
|
AlertTestEtap0, Node: vps, Summary: …".
|
|
4. **Rollback czysty**: reguła usunięta, reload, firing=0.
|
|
|
|
Zamyka pending z 2026-06-30 („czy watchdog realnie polluje" — recon 2026-07-02
|
|
potwierdził konfigurację, dziś potwierdzone działanie end-to-end). Reguła testowa
|
|
NIE trafiła do repo — to diagnostyka, nie architektura; katalog `rules/` ma
|
|
nadal tylko `liveness.yml`.
|
|
|
|
### Realny dowód „czemu cutover" — chelsty NOMINAL-zonk
|
|
|
|
Panel agents.okit.pl pokazuje **chelsty NOMINAL + Runtime online, mimo że chelsty
|
|
jest OFFLINE od 34 dni** (`tailscale status`). U wszystkich węzłów: Last Seen
|
|
„Invalid Date", Connectivity/Incidents `undefined`, a status NOMINAL — observer
|
|
NIE egzekwuje świeżości `last_seen` (bug TTL wraca, patrz backlog „Observer
|
|
staleness"). Cutover na Prometheus `up{}` to naprawia: chelsty nie-scrape'owany →
|
|
down, nie fałszywie NOMINAL.
|
|
|
|
Snapshot panelu potwierdził też dwa zaległe drobiazgi (dopisane do backlogu):
|
|
|
|
- **Ghosty B wróciły/nieposprzątane** — hash-prefixed kontenery control-plane
|
|
widoczne na VPS (wpis „zniknęły" z 2026-07-02 zdezaktualizowany).
|
|
- **elasticsearch + diskover w stanie error na PIHA** — usunięte w module 0
|
|
(2026-07-02), ale observer wciąż je zna i raportuje.
|
|
|
|
---
|
|
|
|
## PLAN — następne etapy cutoveru (osobne sesje)
|
|
|
|
- **Etap 1 — shadow-read**: observer czyta OBA źródła (eventy I Prometheus
|
|
`up{}`), pisze nienaruszające pola `prom_*` w `nodes.json`, loguje rozbieżności,
|
|
NIC nie przełącza (parallel-run, fail-open). Realna zmiana w
|
|
`observer.py:312-323` → worktree/CC.
|
|
- **Etap 2 — analiza**: ≥ 7 dni zgodności → klasyfikacja rozbieżności
|
|
(semantyka vs bug) → decyzja mappingu (rekomendacja: `timestamp(up)` jako
|
|
prom-last_seen przez istniejące `compute_liveness`).
|
|
- **Etap 3 — przełączenie per-węzeł** za flagą `PROM_LIVENESS_NODES`:
|
|
najpierw solaria+lustro (najmniejsza szkoda przy pomyłce), potem vps+piha.
|
|
**chelsty-infra ZOSTAJE na eventach.** Rollback = wyczyszczenie flagi.
|
|
|
|
---
|
|
|
|
## Wnioski
|
|
|
|
- **Etap 0 zamknął fundamentalną niepewność wiszącą od 2026-06-30**: „czy tor
|
|
alertowy Prometheus→watchdog→Telegram w ogóle działa" przestało być wnioskowaniem
|
|
z konfiguracji (recon 2026-07-02), a stało się faktem dowiedzionym w produkcji.
|
|
Dalsze etapy cutoveru budują na sprawdzonym fundamencie, nie na założeniu.
|
|
- **verify-before-fix w reconie obalił założenie architektoniczne**: observer NIE
|
|
jest jednym modułem w `services/control-plane/src/` — to `scripts/observer/observer.py`
|
|
+ wydzielona maszyna stanów `liveness.py` importowana przez trzy konsumentów.
|
|
Bez reconu plan cutoveru celowałby w złe miejsce.
|
|
- **Test punktowy (reguła for:0s + rollback) to tani sposób na dowód bojowy toru
|
|
alertowego** — bez czekania na realną awarię i bez commitowania diagnostyki do repo.
|
|
- Hashe sesji: `d94bb38` (recon cutoveru); Etap 0 = czynność operatorska na
|
|
runtime (bez commitu, zgodnie z planem z reconu).
|