# Sesja 2026-06-17 — Vikunja OIDC+GitOps · Observer heartbeat-TTL · panel-source

## Zrobione i wdrożone

### 1. Vikunja: OIDC (Forgejo) + migracja do GitOps — commit e5c6bfe
- Problem: brak guzika Forgejo na loginie vikunja.okit.pl (PIHA).
- Root cause (dwie warstwy): (a) kontener rozwiązywał forgejo.okit.pl po publicznym DNS → flaky ingress → discovery padał; (b) WŁAŚCIWY blocker: npm "Local" Access List na proxy forgejo.okit.pl blokował źródłowy IP kontenera — bridge PIHA używa puli 192.168.x.x (NIE 172.16/12), egress jako gateway 192.168.112.1, spoza allowlisty.
- Fix: extra_hosts "forgejo.okit.pl:192.168.31.5" (npm LAN IP) w serwisie vikunja + Allow 192.168.0.0/16 w npm Local Access List (tab Rules). Po obu: discovery 200, login działa.
- Migracja: manualny deploy /home/pi/vikunja → services/vikunja/ w repo (worktree task/vikunja-gitops-migration). config.yml: provider "forgejo", authurl "https://forgejo.okit.pl/" (z trailing slash = issuer match), redirecturl "https://vikunja.okit.pl/auth/openid/". Wolumeny przypięte po nazwie (vikunja_vikunja_db / vikunja_vikunja_files). Sekrety w .gitignore .env. Brak healthchecku w obrazie (brak wget/curl).
- Cutover DONE na PIHA: pg_dump ~/vikunja-pre-migration.sql (72880 B), down starego stacka (wolumeny zachowane), git pull (chmod 600 ~/.ssh/id_rsa), .env, up, login + taski OK.
- PENDING: rm /home/pi/vikunja (trzymać .sql ~1 dzień); config npm (access-list + proxy hosts) żyje TYLKO w bazie npm, nie w GitOps.

### 2. Observer: heartbeat-TTL (martwy node ≠ NOMINAL) — commit 5f1528e, MERGED
- Problem: CHELSTY-INFRA NOMINAL mimo 16 dni offline. Status ustawiany tylko eventami, nigdy nie wygasał po TTL.
- Fix: 3-stopniowa liveness (fresh/stale/dead) z now-last_seen, liczona co cykl. Progi: always-on fresh≤180s/dead>600s; remote (chelsty-*/role remote) fresh≤900s/dead>3600s; override env LIVENESS_TTL_*. Wspólny helper services/control-plane/src/liveness.py (compute_liveness, ttls_for, node_health=worse-of, parse_ts int+ISO; brak last_seen → UNKNOWN, NIE degraduje). Read-time net w obu UI (operator_ui + agent-system/webui/web.py zwracają LISTY z polem health). Observer emituje node_stale/node_offline/node_online; supervisor → alert_only (dedup+1h cooldown). 89 testów green.
- Deploy (messy, done): wymaga REBUILD (operator_ui + webui mają COPY src; observer mountuje /repo). Wpadki: przypadkowy up --build control-plane na SOLARIA (crash-loop, sprzątnięte down); VPS pierwszy up --build padł w połowie → down + up --build, 4 kontenery healthy. PIHA agent-system rebuilt.
- ZWERYFIKOWANE U ŹRÓDŁA: curl localhost:18180/nodes na VPS (operator_ui) = 5 nodów poprawnie (vps=nominal, chelsty-infra=ERROR, piha=ERROR, solaria=nominal, lustro=nominal). Fix działa autorytatywnie.
- Brak świeżego alertu offline dla chelsty/piha = oczekiwane (nody padłe przed startem nowego observera → baseline tłumi transition; alertują tylko NOWE przejścia).

## Otwarte / odkryte tej sesji

### PANEL agents.okit.pl czyta ROZJECHANY world-state (NOWE, NIEROZWIĄZANE)
- agents.okit.pl (npm na VPS, proxy_host 5.conf) → set $server 100.108.208.3, port 18180, http.
- 100.108.208.3 = PIHA (potwierdzone tailscale status). :18180 na PIHA = agent-system-webui.
- Czyli panel = webui PIHA czytający LOKALNY /opt/homelab/world/nodes.json (materializowany przez runtime-materializer PIHA) — inny, starszy world-state niż autorytatywny observer na VPS.
- Objawy: 4 nody (chelsty zamiast chelsty-infra, brak lustro) zamiast 5; Last Seen: Invalid Date → last_seen nieparsowalny → compute_liveness UNKNOWN → z designu nie degraduje → wszystko NOMINAL. Fix JEST tam wdrożony, ale na zepsutych danych nic nie robi.
- DWA rozjechane world-state'y: VPS observer (autorytatywny, poprawny) vs materializer PIHA (to widzi panel, stale/broken).
- Plus: panel zaśmiecony duchami *_control-plane-* (hash-prefixed martwe ID kontenerów po deploy-churnie).
- DO ZROBIENIA (świeży task): czemu materializer PIHA daje Invalid Date + inny zestaw nodów; który UI kanoniczny (operator_ui VPS vs agent-system-webui PIHA); cleanup duchów. Stopgap dostępny: przepiąć 5.conf na VPS-lokalny operator_ui (set $server 127.0.0.1, port 18180) + reload npm → panel pokaże prawdę natychmiast (ryzyko: inny front).

## Backlog (priorytet)
1. PIHA delivery+permissions — PRIORYTET. node-agent nie pisze /opt/homelab/events/piha/ (Permission denied); rsync "No user exists for uid 1000"; ~6-dniowa luka → piha pokazuje DEAD mimo że żyje. (To przypadek "push zepsuty vs node down" — rozróżni go cross-check Prometheus blackbox.)
2. npm config → GitOps (access-list 192.168.0.0/16 + proxy hosts tylko w bazie npm).
3. Vikunja cleanup: rm /home/pi/vikunja (trzymać .sql ~1 dzień).
4. Prometheus fleet-liveness (większy): blackbox_exporter po Tailscale MagicDNS, targety z inventory/topology.yaml, Alertmanager (Telegram), observer czyta probe_success jako PRIMARY + event-TTL jako fallback. Obecny Prometheus na PIHA (9090, bez Alertmanagera) scrape'uje hardcoded 192.168.31.x (martwe up=0) i MIJA nody tylko-Tailscale (VPS, chelsty).
5. Observer housekeeping: ghost-dir be17cb6eb0f6 + puste 2026-05-* w events/ + fallback NODE_NAME→hex container-ID.
6. SOLARIA: docker image prune (stray control-plane images po przypadkowym deployu).
7. Panel world-state reconciliation + ghost cleanup (sekcja wyżej).

## Uwaga
task/kb-foundations (commit 2c9ac78, knowledge-base) zaparkowany na swojej gałęzi; master zresetowany do origin/master — nic nie stracone, NIE ruszać (inny chat).
