docs(kb): sesja 2026-06-22 — spine relokowany na PIHA + przygotowanie hosta

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
oskar 2026-06-22 22:16:24 +02:00
parent c32e050d56
commit c0ffb6abf7
2 changed files with 105 additions and 3 deletions

View file

@ -2,7 +2,7 @@
> Master-dokument inicjatywy. Stoi ponad dokumentami per-projekt (`kb-01-email-design.md`, …).
> Cel: każda kolejna sesja / Claude Code startuje z pełnym kontekstem ustaleń.
> Status: faza *docs*. Implementacja jeszcze nie ruszyła.
> Status: implementacja ruszyła. Etap 1 (fundament) done; spine Postgres+pgvector stoi na **PIHA** (always-on); bulk importer Gmaila następny.
---
@ -49,7 +49,7 @@ Dwa dolne tiery są per-filar i neutralne. Dwa górne są wspólne dla wszystkic
3. **Czas + miejsce jako byty pierwszej klasy od dnia zero.** Uniwersalny klucz złączeń między źródłami, karmiony OwnTracks. Nie da się retrofitować bez re-ingestu — stąd w kopercie od startu.
4. **Local-first / privacy.** Korpus (bank + prywatne zdjęcia + maile) → wszystko lokalnie. Embeddingi i modele na SOLARIA (GPU + ollama). Zero chmury dla danych wrażliwych.
5. **Protokół, nie provider.** Ingest pisany przeciw standardom (JMAP, IMAP, WebDAV), nie przeciw firmie → przenośność.
6. **Jeden spine: Postgres + pgvector.** Koperta + wektory (+ później encje + punkty OwnTracks) w jednym store. Mniej ruchomych części.
6. **Jeden spine: Postgres + pgvector.** Koperta + wektory (+ później encje + punkty OwnTracks) w jednym store. Mniej ruchomych części. Spine stoi na **PIHA** (Raspberry Pi 5, always-on) — zapytania KB muszą działać 24/7, a SOLARIA bywa offline. SOLARIA zostaje do GPU/embeddingów (bge-m3) i indexera.
7. **Warstwa 4 nie jest waterfallem.** Kontrakt encji (warstwa 3) definiujemy wcześnie — przy 2 źródłach; po drugim źródle stawiamy *cienką* wersję warstwy 4, by udowodnić cross-source linking; dopiero potem dokładamy resztę.
---
@ -125,7 +125,13 @@ Pierwszy job: `jobs/gmail-bulk-import/` — jednorazowy bulk importer Gmail Take
- ✅ `packages/kb-mail``envelope` / `db` (asyncpg) / `archive` (append-only .eml)
- ✅ 15 testów unit + 5 integration (mark `integration`, wymaga `KB_TEST_DSN`)
~~Etap 2: jednorazowy bulk importer Gmail (mbox/Takeout → archiwum).~~ **KOD GOTOWY** (2026-06-24) — nie uruchomiony.
**Etap 2a: relokacja spine SOLARIA→PIHA + deploy** — ZROBIONE (2026-06-22).
- ✅ override SOLARIA usunięty; `hosts/piha/runtime/kb-postgres/docker-compose.override.yml` (mem_limit 1g, tuning pod małą maszynę), obraz `pgvector/pgvector:pg16` arm64
- ✅ PIHA przygotowany: 4GB swap + `cgroup_enable=memory` (mem_limit działa), volume `kb_postgres_data` na NVMe
- ✅ deploy na PIHA: kontener healthy, schemat `envelope` + extension `vector` zweryfikowane
- ⏳ zostaje: transfer archiwum/.eml na PIHA NVMe (docelowo), poprawka `KB_TEST_DSN` (solaria→piha) w testach
~~Etap 2b: jednorazowy bulk importer Gmail (mbox/Takeout → archiwum).~~ **KOD GOTOWY** (2026-06-24) — nie uruchomiony.
- ✅ `jobs/gmail-bulk-import/` — CLI importer bez Dockera (pip install -e na PIHA)
- ✅ entities[]: manifest załączników (filename, content_type, size, sha256) od dnia zero

View file

@ -0,0 +1,96 @@
# Sesja 2026-06-22 — KB spine relokowany na PIHA + przygotowanie hosta
## Cel
Przenieść spine KB (Postgres + pgvector) z SOLARIA na PIHA, przygotować host PIHA pod
kontener z twardym limitem pamięci, zdeployować i zweryfikować schemat. SOLARIA bywa
offline — zapytania KB muszą działać 24/7, więc spine musi stać na always-on maszynie.
---
## DECYZJA
- **Spine Postgres + pgvector przeniesiony SOLARIA → PIHA.** Powód: PIHA (Raspberry Pi 5)
jest always-on, SOLARIA bywa offline; zapytania KB mają działać 24/7. SOLARIA zostaje do
GPU/embeddingów (bge-m3) i indexera.
- **Archiwum maili `.eml` docelowo też na PIHA** (NVMe).
---
## PIHA — przygotowanie hosta
- **Swap:** dodano 4GB swapfile (`/swapfile`), utrwalony w `/etc/fstab`. Brak swapa był
ryzykiem OOM dla Home Assistant.
- **Cgroup memory:** kernel nie eksponował cgroup memory controllera → dopisano
`cgroup_enable=memory cgroup_memory=1` do `/boot/firmware/cmdline.txt`
(backup: `cmdline.txt.bak`) + reboot. Po reboocie `cgroup.controllers` zawiera `memory`,
docker `mem_limit` faktycznie działa (wcześniej był ignorowany).
---
## Relokacja w git
Praca w worktree `task/kb-postgres-piha`, zmergowana do master jako commit **2b3cb89**.
- Override SOLARIA (`hosts/solaria/runtime/kb-postgres/`) **usunięty**;
wpis z `hosts/solaria/services.yaml` zdjęty.
- Dodany `hosts/piha/runtime/kb-postgres/docker-compose.override.yml`:
- `mem_limit: 1g`, `mem_reservation: 512m` (soft reservation ignorowany przez kernel —
nieszkodliwe; twardy `mem_limit` chroni HA przed OOM).
- Tuning Postgresa pod małą maszynę: `shared_buffers 256MB`, `effective_cache_size 512MB`,
`work_mem 8MB`, `maintenance_work_mem 64MB`, `max_connections 30`.
- Obraz `pgvector/pgvector:pg16` potwierdzony **arm64**.
- Named volume `kb_postgres_data` na **NVMe** (docker `data-root = /home/docker`
`/dev/nvme0n1p3`, ~170GB wolne).
- `inventory/topology.yaml` + `hosts/piha/services.yaml` — wpisy przeniesione.
---
## Deploy na PIHA
- Kontener **healthy**.
- Schemat `envelope` + extension `vector` zweryfikowane w działającej bazie.
- `mem_limit 1g` zaaplikowany po **force-recreate** (zwykły `up` nie podmienia limitu).
---
## Google Takeout (bulk Gmail)
- Pobrany: **15GB zip**, jeden plik; Mail po rozpakowaniu **~26.9GB**.
- Leży na **SOLARIA `~/Downloads`**, NIE rozpakowany jeszcze.
- Docelowo: transfer na PIHA NVMe → import. Czeka na importer (etap 3).
---
## Higiena git
- Cała praca przez worktree: `task/kb-foundations` (zmergowany i sprzątnięty),
`task/kb-postgres-piha` (zmergowany).
- Master deploy-only, czysty.
---
## GOTCHA PIHA (do zapamiętania)
`~/.ssh/id_rsa` na PIHA miał perms **0640**`git fetch` przez SSH padał
(`bad permissions`). Fix: `chmod 600 ~/.ssh/id_rsa`. To ta sama klasa problemów
uid/permisji co wcześniej na PIHA — przy onboardingu PIHA warto sprawdzać perms kluczy.
---
## Następny krok
**Importer bulk Gmail** (worktree `task/kb-gmail-import`):
- CLI w `packages/kb-mail`, `mbox → archiwum (.eml) + envelope`, **idempotentny**, `--dsn` na PIHA.
- Potem: transfer Takeout na PIHA NVMe + run.
---
## BACKLOG (osobno, nieruszane w tej sesji)
- **`hosts/piha/capabilities.yaml` rozjazd danych:** mówi `memory 4GB` / `sd-card 32GB`;
realnie **8GB RAM + NVMe 170GB**. Ten sam typ rozjazdu danych co przy 8-dniowej ślepocie
floty — do poprawienia.
- **`KB_TEST_DSN` w `packages/kb-mail/tests/test_db.py`** — wskazuje na solaria, powinien piha.
- **Deklaratywny zapis `cgroup_enable` + swap dla PIHA** — firmware/host config jest poza
obecnym GitOps; rozważyć jak go ująć.