Commit graph

337 commits

Author SHA1 Message Date
oskar 07a0fe097b docs(sesja): 2026-07-10 Deploy 1 Paperless LIVE (OCR+OIDC dziala) + swap PIHA 8Gi + npm-API w akcji + lekcje 2026-07-10 18:29:10 +02:00
oskar 5daae77e2f feat(scripts): npm_api.py — CLI do zarzadzania npm PIHA+VPS przez REST API
token/list-hosts/list-certs/set-cert/create-host, dry-run domyslny dla
zmian (--apply wymagane), stdlib urllib (zero-dep). Adresy npm@VPS
przez Tailscale (100.95.58.48:81), NIE public IP.

+ docs/backlog.md: npm@VPS admin panel :81 publicznie osiagalny —
brak override ograniczajacego bind do mesh/localhost.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-10 14:57:42 +02:00
Oskar Kapala 5db6ffa1f3 docs(sesja): 2026-07-09 KB configi 9 decyzji (NC->PIHA) + wzorzec Nextcloud-twierdza + Gokapi public share 2026-07-09 18:34:19 +02:00
Oskar Kapala 6e80b92348 chore(control-plane): enable Prometheus shadow-read liveness — start etap 2 parallel-run 2026-07-09 18:29:16 +02:00
Oskar Kapala fbf9e7501d feat(gokapi): config publicznego file-share na VPS (share.okit.pl, E2E, Tailscale-bind za npm@VPS, disk-protection) — do deployu
Nextcloud zostaje prywatny (mesh/kapala.org); Gokapi to osobny publiczny
serwis do wysylania linkow do plikow na zewnatrz (Firefox Send alt).
owner_node=vps, storage lokalny dysk (nie S3), E2E encryption ON, port
53842 bindowany tylko na TAILSCALE_BIND_IP (hairpin NAT przez npm@VPS,
nigdy 0.0.0.0). Cutover checklist w README (DNS, wildcard *.okit.pl na
npm@VPS, setup wizard) — nie zdeployowane w tym commicie.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 17:29:28 +02:00
Oskar Kapala 7e5577c58f feat(kb): configi Paperless/Nextcloud wg 9 decyzji — NC na PIHA, domeny kapala, Redis requirepass, backup SOLARIA, NC pin 34
Co zrobione:
- Nextcloud host = PIHA (always-on dla aktywnego uzycia), owner_node +
  LAN_BIND_IP/TRUSTED_PROXIES w .env, README zaktualizowane
- Redis brokera Paperlessa: requirepass, PAPERLESS_REDIS_PASSWORD w .env
  po obu stronach (PIHA + worker@SOLARIA), healthchecki z auth
- Domeny potwierdzone: paper.kapala.org, cloud.kapala.org (Cloudflare
  DNS-only -> Tailscale PIHA, wildcard cert juz pokrywa) — udokumentowane,
  nic nie utworzone
- Backup Paperlessa zatwierdzony: document_exporter + rsync/borg -> SOLARIA,
  retencja 7/4/6, offsite jako future-note
- Nextcloud pin: 34-apache (zweryfikowany aktualny stable, endoflife.date)
- Whoosh fallback-worker: zaakceptowane bez zmian
- Porty/wylaczenie local login/sizing OCR-workera: przeniesione z "decyzji"
  na "TODO przy deployu"
- DECYZJE-do-podjecia.md zaktualizowane: wszystko poza portami/loginem/
  sizingiem przeniesione do "Rozstrzygniete"

Tylko edycja configow w repo — nic nie zdeployowane, zadne kontenery nie
byly ruszane, DNS/vhosty nie utworzone.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 16:17:27 +02:00
Oskar Kapala e5ecefe2b7 feat(observer): shadow-read Prometheus up{} liveness with mismatch logging (cutover etap 1, no switching)
Observer now optionally (PROM_SHADOW_URL) queries Prometheus up{} once per
cycle and LOGS SHADOW_LIVENESS_MISMATCH when its event-driven liveness
disagrees. Parallel-run only: compute_liveness and _emit_node_transition are
untouched; authoritative liveness stays 100% event-driven. Fail-open on any
Prometheus error (down/timeout/bad JSON -> {}). 9 new tests, incl. proof that
shadow-read does not change node_info liveness/status.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 15:38:20 +02:00
oskar 4965866644 docs: session log 2026-07-07 immich upload fix + pimain backup retention 2026-07-07 23:01:48 +02:00
oskar 7d6fd7df37 docs(sesja): 2026-07-07 okit.pl faza 1 (wildcard *.okit.pl) + przepiecie 9 hostow bulk-SQL + lekcja npm cert regeneracja 2026-07-07 22:39:23 +02:00
oskar 237df1cd2e docs(infra): migracja okit.pl 42.pl->Cloudflare — faza 0 done+zweryfikowana, split-horizon Pi-hole, plan faz 1-2 2026-07-07 20:46:57 +02:00
oskar 2aa47963b3 feat(kb): configi Paperless (PIHA) + OCR-worker (SOLARIA, NFS split-host) + Nextcloud — do review, split-host NFS zweryfikowany (GH #3900), 9 decyzji w DECYZJE-do-podjecia.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 22:10:38 +02:00
oskar 670fa7a5e4 docs(backlog): ghosty B wróciły + elasticsearch/diskover error na PIHA; Etap 0 (tor Prometheus→watchdog→Telegram) oznaczony jako udowodniony
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 18:34:38 +02:00
oskar 3d437976b1 docs(sesja): 2026-07-06 — recon cutoveru wmergowany + Etap 0 udowodniony end-to-end (AlertTestEtap0)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 18:34:32 +02:00
oskar d94bb38e69 docs(infra): prometheus cutover recon — mapa starego toru liveności + plan etapowy
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 15:17:05 +02:00
oskar cbb910d856 feat(llm-gateway): wciagniecie shadow-serwisu z PIHA do GitOps
Kod zyl tylko na dysku PIHA w /opt/llm-gateway (bez gita). Przeniesiony do
services/llm-gateway/ pod pelny wzorzec homelaba:

- app/main.py: kod 1:1 z PIHA + OLLAMA_URL/CHAT_MODEL/CODE_MODEL
  nadpisywalne przez env (defaulty bez zmian)
- docker-compose.yml: bind TYLKO do Tailscale IP (${TAILSCALE_BIND_IP},
  wzorzec fleet-prometheus), nie 0.0.0.0 jak w starym compose
- service.yaml, env.example (bez sekretow), healthcheck.sh, README, testy
- hosts/piha/runtime/llm-gateway: mem_limit 256m (PIHA jest RAM-bound)
- rejestracja w hosts/piha/services.yaml i inventory/topology.yaml

Zepsuty /opt/llm-gateway/docker-compose.yml (zduplikowany klucz ports)
celowo NIE przeniesiony.

DoD: pytest 4 passed; docker build + smoke run OK (GET / -> gateway ok).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 15:08:33 +02:00
Oskar Kapala 5cfb45227f fix(capabilities): saturn RAM 16->14 (usable, konwencja free -g) + errata audytu: SATURN arm64->x86_64
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 14:58:21 +02:00
Oskar Kapala b51af01fa7 fix(capabilities): saturn RAM/storage + solaria CPU/storage — reconcile with real hardware (audit 2026-06-30)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 14:45:53 +02:00
oskar 8ccd58b8a1 docs(sesja): modul 0 wykonany (+1Gi PIHA) + migracja forgejo/vikunja na kapala.org (OIDC gotcha) 2026-07-02 17:37:07 +02:00
oskar bb9ddde91d docs(backlog): zamkniecia po reconie 2026-07-02 + followupy z rozbrajania min
Zamkniete: bug B (ghost kontenery — zniknely), pending poll-Prometheus-watchdog
(potwierdzony), miny #1/#2/#3 z inwentaryzacji. Dodane followupy: wpisy hostowe
forgejo/mosquitto, mem_limit mosquitto@VPS, mosquitto per-host (chelsty-infra),
broker :1883 w topology, pi-watchtower-1 restart-loop, alias lustro, mem_limit
fleet-prometheus. Ocena joplin-db postgres:18 zdezaktualizowana (PG18 GA).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 17:30:48 +02:00
oskar 0bcf5e505f docs(sessions): sesja 2026-07-02 — recon-weryfikacja inwentaryzacji, trzy miny rozbrojone
Recon Fable (57a6dff): bilans 23 rozjazdow (20 aktualnych / 2 zmienione /
1 wyjasniony), dwa pendingi domkniete (poll Prometheus w brain-watchdog
potwierdzony; ghost kontenery B zniknely). Miny: #1 PIHA checkout
(lekcja checkout-vs-reset), #2 slepy control-plane na SATURN (compose down),
#3 owner_node (886bc85).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 17:30:48 +02:00
oskar b6d55949ba fix(vikunja): PUBLICURL na vikunja.kapala.org 2026-07-02 17:28:56 +02:00
oskar f454ac7448 fix(vikunja): OIDC na forgejo.kapala.org + redirect vikunja.kapala.org (cert okit.pl wygasl) 2026-07-02 17:24:51 +02:00
oskar 886bc85e0b fix(inventory): correct owner_node — forgejo→piha, mosquitto→vps (per 2026-07-02 verify)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:48:12 +02:00
oskar 6b35afd2ea docs(infra): egzekucja odchudzania PIHA — ES+diskover ubite (+1.0Gi), llm-gateway/immich zostają
Faza 2 modułu 0 po review Oskara: elasticsearch+diskover usunięte (compose down,
dane esdata zostawione na dysku), available 2.8Gi -> 3.8Gi, kryterium >=1.5Gi
spełnione. llm-gateway udokumentowany (własny router LLM -> Ollama@SOLARIA,
źródło tylko w /opt/llm-gateway — archiwizacja w backlogu); immich zostaje na
PIHA na stałe (24/7, SOLARIA sesyjna).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:44:57 +02:00
oskar f1e302d19b docs(infra): audyt odchudzania PIHA — 917Mi bezpieczne (ES+diskover+llm-gateway), immich->SOLARIA kandydat 2026-07-02 16:11:41 +02:00
oskar 57a6dffc5e docs(infra): weryfikacja inwentaryzacji 2026-06-30 — stan na 2026-07-02
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 15:26:18 +02:00
oskar 22adfb1c8e docs(kb): kb-02 moduly 4-5 — Nextcloud + ingest->koperta (komplet szkieletow 0-5) 2026-07-02 15:09:40 +02:00
Oskar Kapala c5dd1ecb56 docs(kb): kb-02 architektura dokumentow — master + moduly 0-3 (split Paperless PIHA/OCR SOLARIA) 2026-07-01 21:56:07 +02:00
Oskar Kapala 727cb999ef docs(sesja): inwentaryzacja floty 2026-06-30 + dysk SATURN + safeclean; backlog 23 rozjazdy 2026-06-30 19:56:50 +02:00
Oskar Kapala 229f85bd9b docs(infra): inwentaryzacja floty 2026-06-30 — 23 rozjazdy repo↔rzeczywistość 2026-06-30 19:40:50 +02:00
Oskar Kapala 4055a8ffab docs(backlog): oznacz kroki 4+5 Prometheus jako ZROBIONE, dopisz tech-debt log PROMETHEUS_URL
Kroki 4 (reguły liveness d417000) i 5 (watchdog poll 62d6fc0) z planu monitoringu zamknięte.
Nowy wpis aktywny: brain-watchdog nie loguje PROMETHEUS_URL przy starcie — utrudnia weryfikację.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 19:29:24 +02:00
Oskar Kapala 0656635793 docs(sesja): fleet-prometheus liveness — reguły NodeDown + watchdog→Prometheus poll
Sesja 2026-06-30: commits d417000 (rules/liveness.yml, NodeDown inactive=OK) i 62d6fc0
(brain-watchdog/check_prometheus_alerts, architektura A, 12 testów). Incydent PIHA
divergent branches — praca uratowana verify-before-reset. PENDING: end-to-end firing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 19:29:20 +02:00
Oskar Kapala 62d6fc066b feat(brain-watchdog): poll Prometheus /api/v1/alerts as second alert source (Telegram)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 18:51:34 +02:00
Oskar Kapala d4170004e7 feat(fleet-prometheus): add liveness alert rules for always-on nodes (vps, piha)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 16:42:52 +02:00
Oskar Kapala 831bbedffa docs(sesja): kapala.org → Cloudflare wildcard DNS-01, HA i Immich na mesh
Sesja 2026-06-30: migracja DNS kapala.org z 42.pl na Cloudflare, wildcard
*.kapala.org przez DNS-01, ha/immich.kapala.org przez NPM@PIHA mesh-only.

- nowy session log z root-cause buga "unrecognized name" (NPM duplikuje
  proxy_http_version przy Websockets ON) + wzorzec migracji usługi na mesh
- backlog: gotchas (NPM WS config, CF auto-proxy DKIM) + TODO (migracja
  okit.pl, foty renew, cleanup ha-ken add-on, stale ha.okit.pl)
- topology: nowa sekcja ingress (ha/immich → NPM@PIHA, wildcard cert)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 16:23:57 +02:00
Oskar Kapala 48107ef2c1 docs(backlog): zamknij deploy.sh vps bug + 2 nowe wpisy (prom-reload, chelsty node_exporter)
- 🔴 deploy.sh vps↔control-plane → Zamknięte (fix 3b71707, guard deploy-local.sh)
- krok 2 planu floty (targety 100.x) → ZROBIONE (7d4014e)
- NOWE: deploy-node.sh nie reloaduje config-driven serwisów (cicha rozbieżność deploy↔config)
- NOWE: zbadać chelsty/chelsty-infra node_exporter DOWN z VPS
- Problem B (ghost kontenery) pozostaje otwarty osobno

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 17:30:26 +02:00
Oskar Kapala 39ab34643d docs(kb): sesja 2026-06-26 — fleet-prometheus targety floty + zamknięcie buga deploy.sh vps
- targety node_exporter floty (piha/solaria/lustro) wdrożone (7d4014e)
- fix deploy.sh vps↔control-plane potwierdzony w boju (3b71707)
- PENDING: health-verify targetów w /api/v1/targets nie potwierdzony
- lekcja: nie commitować na master równolegle gdy CC pracuje na wątku (potrójny rebase)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 17:30:19 +02:00
Oskar Kapala 7d4014e512 feat(fleet-prometheus): add piha/solaria/lustro node_exporter scrape targets
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 16:41:09 +02:00
oskar 7a95ab2fff docs(kb): sesja 2026-06-25 — bulk import Gmail uruchomiony (225k kopert na PIHA) 2026-06-26 16:33:17 +02:00
Oskar Kapala 1529911012 docs(backlog): add anomaly-detection liveness idea (mózg learns per-node daily pattern) 2026-06-26 16:20:54 +02:00
Oskar Kapala 3b71707660 fix(deploy): exclude control-plane from node deploy loop — prevents brain teardown via project-name divergence
deploy.sh vps iterates hosts/vps/services.yaml in deploy-node.sh, which
includes control-plane. But control-plane also has a dedicated deploy path
(deploy.sh control-plane → deploy-control-plane.sh → deploy-local.sh) that
runs compose from services/control-plane/. The node loop runs compose from
${REPO_PATH}, so on Compose versions that derive the project name from cwd
the two paths own the containers under different project names. The loop's
`up -d --remove-orphans` then Recreates and tears down the running brain
(observer/supervisor/executor/ui), aborting the loop under set -e. This
wiped the VPS control-plane on 2026-06-25.

Generic guard: skip any service that ships its own services/<svc>/deploy-local.sh.
control-plane stays in services.yaml so the gate (pytest+build) still covers it;
only the destructive loop deploy is skipped. Protects future services with a
dedicated deploy path too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 15:16:42 +02:00
oskar c0ffb6abf7 docs(kb): sesja 2026-06-22 — spine relokowany na PIHA + przygotowanie hosta
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 18:52:35 +02:00
oskar c32e050d56 docs(kb): sesja 2026-06-24 — importer Gmail gotowy + konwencja jobs/ 2026-06-25 17:41:01 +02:00
oskar 254a6808bc fix(piha): capabilities — realny RAM/NVMe + gitignore build dirs
hosts/piha/capabilities.yaml: memory 4→8 GB, storage sd-card/32 GB → NVMe ~477 GB (/home 410 GB)
.gitignore: packages/*/build/ i jobs/*/build/ (wyciekały po pip install -e)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 17:07:11 +02:00
oskar f234280b3a refactor(kb-mail): importer Gmail — entities załączników, --limit, batch, bez Dockera, DSN→PIHA
- Usuwa Dockerfile i docker-compose.yml; job odpalany lokalnie na PIHA (pip install -e)
- _parse_attachments: manifest MIME → entities[]{type,filename,content_type,size,sha256};
  bajty zostają w .eml, wyciąganie/OCR = faza 2
- Batch inserty co 500 wpisów (executemany + ON CONFLICT DO NOTHING); idempotentny
  na skipped przez _eml_ref (mirrors archive._UNSAFE); pełna wznawialność
- --limit N: ucina pętlę po N wiadomościach do testów na próbce
- epoch_fallback: licznik + WARNING gdy Date nieparsowalne/brak
- Nowe stats: msgs_with_attachments, total_attachments, total_attachment_bytes
- DSN w docstringu: localhost:5433/kb i piha:5433/kb; usunięto solaria:5433
- 9 nowych testów (24 razem), wszystkie zielone

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 17:07:11 +02:00
oskar 6dc1d325f1 feat(kb-mail): etap 2 — jednorazowy bulk importer Gmail (mbox → archiwum)
One-shot job `jobs/gmail-bulk-import/` wczytuje plik .mbox z Google Takeout
i importuje każdą wiadomość do archiwum .eml + opcjonalnie do koperty w DB.
Idempotentny (FileExistsError → skip; ON CONFLICT DO NOTHING w DB).
15 testów jednostkowych (bez DB, bez zewnętrznych serwisów) — wszystkie zielone.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 17:07:11 +02:00
oskar 02d0fa391f docs(deployment): add critical warning — deploy.sh vps destroys control-plane (project-name divergence, 2026-06-25 incident)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 16:30:53 +02:00
oskar a17a11bc9d docs(backlog): add 2026-06-25 bugs (deploy.sh vps mina, ghost kontenery, supervisor bez akcji, phantom world-state); close flaky tests + env-file fixes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 16:30:51 +02:00
oskar 2655b4c6f4 docs(sessions): add 2026-06-25 session log (fleet-prometheus etap 1 domknięty + incydent mózgu)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 16:30:47 +02:00
oskar 992ff7ca7c test(control-plane): isolate _make_observer_simple module-state leak — fixes flaky test_incident_lifecycle
The test_run_once_* cases were flaky/order-dependent. Root cause: observer.observer
derives OBSERVER_STATE_FILE from STATE_DIR at import time. The helper patched
STATE_DIR but never OBSERVER_STATE_FILE, so run_once()/_save_checkpoint() wrote the
checkpoint to the real /opt/homelab/state/observer_checkpoint.json. Those node_checkpoints
(tmp paths tagged with a pytest run number) leaked across tests and across pytest runs;
run_once's `file_path > checkpoint` string compare then skipped/kept events based on
run-number ordering. The helper also never restored the module globals it overwrote.

Replace both ad-hoc helpers with an autouse monkeypatch fixture that redirects every
observer path — including OBSERVER_STATE_FILE — into the per-test tmp_path and reverts
them afterward. Tests no longer touch real disk and are deterministic.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 14:48:03 +02:00