fix(kb): przepiecie wszystkich odwolan wewnetrznych po migracji

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>
This commit is contained in:
oskar 2026-08-04 15:12:24 +02:00
parent 89be9b9780
commit 4658089e21
125 changed files with 221 additions and 220 deletions

View file

@ -93,7 +93,7 @@ services:
preflight fills `arch`, `ram_mb`, `docker_present`, `mm_runtime` — do NOT guess these. preflight fills `arch`, `ram_mb`, `docker_present`, `mm_runtime` — do NOT guess these.
Full schema: `scripts/onboard/README.md`. Full schema: `kb/runbooks/node-onboarding-tool.md`.
--- ---

View file

@ -40,7 +40,7 @@ Pipeline stages: **prepare → validate → deploy → verify → diagnose (on f
## Node Onboarding ## Node Onboarding
New nodes are onboarded via `scripts/onboard/` — an idempotent bash tool driven by New nodes are onboarded via `scripts/onboard/` — an idempotent bash tool driven by
`hosts/<node>/node.yaml` manifests (no Ansible). See `scripts/onboard/README.md` for `hosts/<node>/node.yaml` manifests (no Ansible). See `kb/runbooks/node-onboarding-tool.md` for
the full schema, step status table, and gotchas. the full schema, step status table, and gotchas.
Key fields in `node.yaml`: `ssh_user`, `first_contact` (LAN IP — not `.local`), Key fields in `node.yaml`: `ssh_user`, `first_contact` (LAN IP — not `.local`),
@ -93,7 +93,7 @@ Agent → /opt/homelab/actions/pending/<id>.json
→ Executor dispatches to the target node → completed / failed → Executor dispatches to the target node → completed / failed
``` ```
The executor never connects to a node (deliberate — see docs/backlog.md The executor never connects to a node (deliberate — see kb/phases/backlog.md
"Remediacja floty bez SSH"). It writes a dispatch file that the node collects: "Remediacja floty bez SSH"). It writes a dispatch file that the node collects:
| Action type | Inbox | Executed on the node by | | Action type | Inbox | Executed on the node by |

View file

@ -31,29 +31,29 @@ Action approval flow: `pending/` → operator approves → `approved/` → execu
## Repository Structure ## Repository Structure
- `docs/`: [Infrastructure Standards](docs/standards.md) and [Deployment Conventions](docs/deployment.md). - `docs/`: [Infrastructure Standards](kb/subsystems/standards.md) and [Deployment Conventions](kb/subsystems/deployment.md).
- `docs/architecture/PLAN-subsystem-a-2026-07-28.md`: [Current Maintenance Plan (Control Plane)](docs/architecture/PLAN-subsystem-a-2026-07-28.md). - `kb/phases/subsystem-a-naprawa.md`: [Current Maintenance Plan (Control Plane)](kb/phases/subsystem-a-naprawa.md).
- `hosts/`: Host-specific configurations and service assignments. - `hosts/`: Host-specific configurations and service assignments.
- `services/`: Reusable Docker Compose service definitions. - `services/`: Reusable Docker Compose service definitions.
- `scripts/`: Deployment and management scripts. - `scripts/`: Deployment and management scripts.
## Getting Started ## Getting Started
1. **Standardization**: Follow the [Infrastructure Standards](docs/standards.md). 1. **Standardization**: Follow the [Infrastructure Standards](kb/subsystems/standards.md).
2. **Deployment**: See [Deployment Conventions](docs/deployment.md) for how to roll out changes. 2. **Deployment**: See [Deployment Conventions](kb/subsystems/deployment.md) for how to roll out changes.
3. **SATURN**: Remember that SATURN is the only node where commits should be made. 3. **SATURN**: Remember that SATURN is the only node where commits should be made.
## Documentation Index ## Documentation Index
- [Current Maintenance Plan (Control Plane)](docs/architecture/PLAN-subsystem-a-2026-07-28.md) - [Current Maintenance Plan (Control Plane)](kb/phases/subsystem-a-naprawa.md)
- [Infrastructure Standards](docs/standards.md) - [Infrastructure Standards](kb/subsystems/standards.md)
- [Agent Operating Procedures](docs/agents.md) (For AI/Non-Human Agents) - [Agent Operating Procedures](kb/subsystems/agent-operating-procedures.md) (For AI/Non-Human Agents)
- [Deployment Conventions](docs/deployment.md) - [Deployment Conventions](kb/subsystems/deployment.md)
- [Hardware](docs/hardware.md) - [Hardware](kb/nodes/legacy-hardware.md)
- [Networking](docs/networking.md) - [Networking](kb/subsystems/networking.md)
- [Services](docs/services.md) - [Services](kb/subsystems/legacy-services-list.md)
- [Node Capabilities](docs/capabilities.md) - [Node Capabilities](kb/subsystems/capability-model.md)
- [Action Model](services/agent-system/action-model.md) - [Action Model](kb/subsystems/action-approval-model.md)
--- ---
*Note: This repository documents the state of the homelab. Runtime state lives outside the repository in `/opt/homelab`.* *Note: This repository documents the state of the homelab. Runtime state lives outside the repository in `/opt/homelab`.*

View file

@ -90,7 +90,7 @@ przez Tailscale działa bezhasłowo. Verify czysty (arch=aarch64).
## Learnings ## Learnings
(odzwierciedlone też w `scripts/onboard/README.md`) (odzwierciedlone też w `kb/runbooks/node-onboarding-tool.md`)
- mDNS `.local` zawodny do automatyzacji → `first_contact` przez IP lub tailscale, nie `.local` - mDNS `.local` zawodny do automatyzacji → `first_contact` przez IP lub tailscale, nie `.local`
- istniejący node z userem uid=1000: użyj go zamiast tworzyć `oskar` (kolizja uid) - istniejący node z userem uid=1000: użyj go zamiast tworzyć `oskar` (kolizja uid)

View file

@ -130,4 +130,4 @@ Docelowo: osobny worktree per task.
## Tech-debt złapany w sesji ## Tech-debt złapany w sesji
→ wpisany do `docs/backlog.md` → wpisany do `kb/phases/backlog.md`

View file

@ -79,13 +79,13 @@ solaria / piha / chelsty to wciąż **stare root kontenery** node-agenta
(piha Created 2026-05-27, uid 0). Ich mount `/root/.ssh` działa tylko dlatego, (piha Created 2026-05-27, uid 0). Ich mount `/root/.ssh` działa tylko dlatego,
że kontenery są sprzed `user: "1000:1000"`. Pierwszy `--force-recreate` / reboot że kontenery są sprzed `user: "1000:1000"`. Pierwszy `--force-recreate` / reboot
hosta / update obrazu przełączy je na uid 1000 i shipping padnie jak na lustrze. hosta / update obrazu przełączy je na uid 1000 i shipping padnie jak na lustrze.
**NIE RECREATE bez fixu.** Szczegóły i fix: `docs/backlog.md`. **NIE RECREATE bez fixu.** Szczegóły i fix: `kb/phases/backlog.md`.
--- ---
## Tech-debt złapany w sesji ## Tech-debt złapany w sesji
→ wpisany do `docs/backlog.md` (flota-bomba, ha-diag-agent blocked, → wpisany do `kb/phases/backlog.md` (flota-bomba, ha-diag-agent blocked,
poison-quarantine review, `--omit-dir-times`, stale komentarz node_agent.py, poison-quarantine review, `--omit-dir-times`, stale komentarz node_agent.py,
shipping success na `logger.debug`, event-bloat lustro na VPS). shipping success na `logger.debug`, event-bloat lustro na VPS).
@ -96,8 +96,8 @@ fa59625 docs(ha-diag-agent): replace curl verify commands with docker exec
d7e0d31 fix(ha-diag-agent): remove host port mapping for 8087 d7e0d31 fix(ha-diag-agent): remove host port mapping for 8087
### Files changed ### Files changed
services/ha-diag-agent/DEPLOY.md | 4 ++-- kb/runbooks/ha-diag-agent-deploy.md | 4 ++--
services/ha-diag-agent/README.md | 4 ++-- kb/services/ha-diag-agent.md | 4 ++--
services/ha-diag-agent/docker-compose.yml | 3 --- services/ha-diag-agent/docker-compose.yml | 3 ---
services/ha-diag-agent/service.yaml | 3 --- services/ha-diag-agent/service.yaml | 3 ---
4 files changed, 4 insertions(+), 10 deletions(-)) 4 files changed, 4 insertions(+), 10 deletions(-))

View file

@ -120,14 +120,14 @@ services/kb-postgres/service.yaml
services/kb-postgres/env.example services/kb-postgres/env.example
services/kb-postgres/healthcheck.sh services/kb-postgres/healthcheck.sh
services/kb-postgres/init/001_envelope.sql services/kb-postgres/init/001_envelope.sql
services/kb-postgres/README.md kb/services/kb-postgres.md
hosts/solaria/runtime/kb-postgres/docker-compose.override.yml hosts/solaria/runtime/kb-postgres/docker-compose.override.yml
hosts/solaria/services.yaml hosts/solaria/services.yaml
inventory/topology.yaml inventory/topology.yaml
packages/kb-mail/pyproject.toml packages/kb-mail/pyproject.toml
packages/kb-mail/src/kb_mail/{__init__,envelope,db,archive}.py packages/kb-mail/src/kb_mail/{__init__,envelope,db,archive}.py
packages/kb-mail/tests/{conftest,test_envelope,test_archive,test_db,test_migration}.py packages/kb-mail/tests/{conftest,test_envelope,test_archive,test_db,test_migration}.py
docs/kb/kb-00-overview.md (etap 1 done, konwencja packages/) kb/subsystems/kb-overview.md (etap 1 done, konwencja packages/)
CLAUDE.md (sekcja Shared Python Libraries) CLAUDE.md (sekcja Shared Python Libraries)
docs/sessions/2026-06-17-kb-foundations.md docs/sessions/2026-06-17-kb-foundations.md
``` ```

View file

@ -171,7 +171,7 @@ jobs/gmail-bulk-import/pyproject.toml
jobs/gmail-bulk-import/tests/test_importer.py jobs/gmail-bulk-import/tests/test_importer.py
hosts/piha/capabilities.yaml hosts/piha/capabilities.yaml
.gitignore .gitignore
docs/kb/kb-00-overview.md (etap 2 gotowy, konwencja jobs/) kb/subsystems/kb-overview.md (etap 2 gotowy, konwencja jobs/)
docs/kb/kb-01-email-design.md (§8 krok 2 = kod gotowy) kb/subsystems/kb-mail-pillar.md (§8 krok 2 = kod gotowy)
docs/sessions/2026-06-24-kb-gmail-importer.md docs/sessions/2026-06-24-kb-gmail-importer.md
``` ```

View file

@ -108,7 +108,7 @@ docker compose \
--- ---
## Nowe tech-debty (dodane do `docs/backlog.md`) ## Nowe tech-debty (dodane do `kb/phases/backlog.md`)
1. **Rozjazd stanu Docker Compose na VPS** — serwisy `node-agent`, `control-plane` i inne 1. **Rozjazd stanu Docker Compose na VPS** — serwisy `node-agent`, `control-plane` i inne
stworzone innym `project-name` niż `deploy-node.sh` oczekuje; Recreate pada na stale stworzone innym `project-name` niż `deploy-node.sh` oczekuje; Recreate pada na stale

View file

@ -19,7 +19,7 @@ architekturą dokumentów KB. Start od weryfikacji stanu faktycznego wszystkich
- CC (Sonnet 4.6) w worktree `fleet-inventory` zebrał stan faktyczny (docker ps + - CC (Sonnet 4.6) w worktree `fleet-inventory` zebrał stan faktyczny (docker ps +
free/df/nproc) z 4 dostępnych nodów: PIHA, VPS, SOLARIA, SATURN. LUSTRO+CHELSTY free/df/nproc) z 4 dostępnych nodów: PIHA, VPS, SOLARIA, SATURN. LUSTRO+CHELSTY
offline (timeout :22) -> oznaczone UNREACHABLE. offline (timeout :22) -> oznaczone UNREACHABLE.
- Wynik: `docs/infra/inventory-2026-06-30.md` — 23 zpriorytetyzowane rozjazdy. - Wynik: `kb/subsystems/fleet-inventory.md` — 23 zpriorytetyzowane rozjazdy.
- Kluczowe ustalenia: - Kluczowe ustalenia:
- **forgejo** biega na PIHA (always-on), ale `service.yaml owner_node=saturn` — rozjazd - **forgejo** biega na PIHA (always-on), ale `service.yaml owner_node=saturn` — rozjazd
- **mosquitto** biega na VPS, `service.yaml owner=piha`, na PIHA go nie ma - **mosquitto** biega na VPS, `service.yaml owner=piha`, na PIHA go nie ma

View file

@ -10,7 +10,7 @@ links: []
# Sesja 2026-07-02 — Modul 0 (odchudzenie PIHA) + migracja Forgejo/Vikunja na kapala.org # Sesja 2026-07-02 — Modul 0 (odchudzenie PIHA) + migracja Forgejo/Vikunja na kapala.org
## Modul 0 kb-02 — WYKONANY (faza 1 audyt + faza 2 egzekucja) ## Modul 0 kb-02 — WYKONANY (faza 1 audyt + faza 2 egzekucja)
- Audyt CC (read-only): docs/infra/piha-slim-audit-2026-07-02.md - Audyt CC (read-only): kb/audits/piha-slim-2026-07-02.md
- Review Oskara skorygowal audyt: llm-gateway = WLASNY kod (FastAPI-router LLM, - Review Oskara skorygowal audyt: llm-gateway = WLASNY kod (FastAPI-router LLM,
/opt/llm-gateway, proxy do Ollama@SOLARIA) — NIE martwy; immich MUSI byc 24/7 /opt/llm-gateway, proxy do Ollama@SOLARIA) — NIE martwy; immich MUSI byc 24/7
na PIHA (SOLARIA sesyjna) — rekomendacja przeniesienia wykreslona. na PIHA (SOLARIA sesyjna) — rekomendacja przeniesienia wykreslona.

View file

@ -21,7 +21,7 @@ Sesja tylko-recon + minimalne fixy; bez deployów nowych feature'ów.
### Recon-weryfikacja inwentaryzacji floty (commit `57a6dff`, read-only) ### Recon-weryfikacja inwentaryzacji floty (commit `57a6dff`, read-only)
Wynik: `docs/infra/inventory-verify-2026-07-02.md`. Wynik: `kb/subsystems/fleet-inventory-verify.md`.
**Bilans 23 rozjazdów z audytu 2026-06-30**: **Bilans 23 rozjazdów z audytu 2026-06-30**:
- **20 wciąż aktualnych** — nic się samo nie naprawiło. - **20 wciąż aktualnych** — nic się samo nie naprawiło.
@ -100,7 +100,7 @@ Po jednej linii per plik; `owner_node` nie występował nigdzie indziej w repo.
nie rezolwuje z SOLARII; brak formalnego override mem_limit fleet-prometheus nie rezolwuje z SOLARII; brak formalnego override mem_limit fleet-prometheus
w `hosts/vps/runtime/` (siedzi w bazowym compose — kosmetyka). w `hosts/vps/runtime/` (siedzi w bazowym compose — kosmetyka).
Wpisy dodane do `docs/backlog.md` w tej sesji. Wpisy dodane do `kb/phases/backlog.md` w tej sesji.
--- ---

View file

@ -22,7 +22,7 @@ Prometheus → brain-watchdog → Telegram, którego brakowało od 2026-06-30.
### Recon cutoveru — wmergowany (commit `d94bb38`) ### Recon cutoveru — wmergowany (commit `d94bb38`)
Wynik: `docs/infra/prometheus-cutover-recon-2026-07-06.md` (517 linii, read-only, Wynik: `kb/audits/prometheus-cutover-2026-07-06.md` (517 linii, read-only,
zero zmian w kodzie). Kluczowe ustalenia: zero zmian w kodzie). Kluczowe ustalenia:
- **Cutover to podmiana klasyfikacji liveności w JEDNYM miejscu** - **Cutover to podmiana klasyfikacji liveności w JEDNYM miejscu**

View file

@ -46,7 +46,7 @@ maila = ta sama encja, DOWOD zasady kb-00 #7), (3) interfejs pytan (RAG) — pie
realnej uzytecznosci. Dopiero POTEM dopelniac importy (reszta Takeout, zdjecia, transakcje). realnej uzytecznosci. Dopiero POTEM dopelniac importy (reszta Takeout, zdjecia, transakcje).
## TODO nastepne ## TODO nastepne
- MODUL 5 (koperta + ingest + embeddingi + cross-source) — docs/kb/modules/05-documents-ingest.md - MODUL 5 (koperta + ingest + embeddingi + cross-source) — kb/phases/kb-m5-documents-ingest.md
- Import probki zalacznikow z maili (kilkaset, nie 70k) — do zbudowania RAG - Import probki zalacznikow z maili (kilkaset, nie 70k) — do zbudowania RAG
- Interfejs pytan / RAG — warstwa uzytkowa - Interfejs pytan / RAG — warstwa uzytkowa
- Deploy 3 (Nextcloud), Deploy 4 (Gokapi) — configi gotowe, czekaja - Deploy 3 (Nextcloud), Deploy 4 (Gokapi) — configi gotowe, czekaja

View file

@ -27,12 +27,12 @@ parsowany z nazwy `evt-<node>-<ts>-...` (fallback mtime, **nigdy 0** dla
istniejącego pliku — 0 = leksykalne "starszy niż checkpoint" = dokładnie ten istniejącego pliku — 0 = leksykalne "starszy niż checkpoint" = dokładnie ten
poison), migracja starych path-checkpointów przy starcie. Zdeployowany na VPS poison), migracja starych path-checkpointów przy starcie. Zdeployowany na VPS
(observer `StartedAt` 07-14). Zweryfikowany dziś jako kompletny i zdeployowany. (observer `StartedAt` 07-14). Zweryfikowany dziś jako kompletny i zdeployowany.
Szczegóły: `docs/backlog.md` (sekcja "Bug: checkpoint observera po ścieżce Szczegóły: `kb/phases/backlog.md` (sekcja "Bug: checkpoint observera po ścieżce
leksykalnej"). leksykalnej").
### 2. docs(infra) analiza Etapu 2 shadow-run (Fable, `8fec62d`) ### 2. docs(infra) analiza Etapu 2 shadow-run (Fable, `8fec62d`)
`docs/infra/prometheus-shadow-etap2-analiza-2026-07-15.md` — 165 mismatchy `kb/phases/prometheus-cutover-etap2.md` — 165 mismatchy
`SHADOW_LIVENESS_MISMATCH` solaria/lustro w dobie 2026-07-14 WYJAŚNIONE: dwa `SHADOW_LIVENESS_MISMATCH` solaria/lustro w dobie 2026-07-14 WYJAŚNIONE: dwa
nocne wyłączenia węzłów (lustro 21:30 UTC — regularny power-off, solaria nocne wyłączenia węzłów (lustro 21:30 UTC — regularny power-off, solaria
21:34 UTC). Wzorzec `event=fresh prom=down` to **nie** "żywy węzeł niewidziany 21:34 UTC). Wzorzec `event=fresh prom=down` to **nie** "żywy węzeł niewidziany

View file

@ -31,7 +31,7 @@ links: []
### 1. RECON lustro shipping (Fable, commit `542bba4`) ### 1. RECON lustro shipping (Fable, commit `542bba4`)
`docs/infra/lustro-shipping-recon-2026-07-16.md` — 1507 mismatchy `lustro event=dead prom=up` w trwałym logu WYJAŚNIONE: (a) wczorajszy kontrolowany test (node-agent stał 3h20m, nie 15 min jak zakładano) + (b) poranny boot-race 56s. **Werdykt: shipping lustro działa, ZERO recurring problemu.** Prometheus 0 pomyłek w 48h — wzmacnia rekomendację GO dla Etapu 3 cutoveru. `kb/audits/lustro-shipping-2026-07-16.md` — 1507 mismatchy `lustro event=dead prom=up` w trwałym logu WYJAŚNIONE: (a) wczorajszy kontrolowany test (node-agent stał 3h20m, nie 15 min jak zakładano) + (b) poranny boot-race 56s. **Werdykt: shipping lustro działa, ZERO recurring problemu.** Prometheus 0 pomyłek w 48h — wzmacnia rekomendację GO dla Etapu 3 cutoveru.
Znaleziska poboczne: lustro biega na obrazie sprzed 5 tyg (deploy-node bez `--build` — patrz fix #2 niżej); fake-hwclock boot-race (RPi bez RTC — pierwszy event po boocie ma stary stempel, dropnięty przez timestamp checkpoint). Znaleziska poboczne: lustro biega na obrazie sprzed 5 tyg (deploy-node bez `--build` — patrz fix #2 niżej); fake-hwclock boot-race (RPi bez RTC — pierwszy event po boocie ma stary stempel, dropnięty przez timestamp checkpoint).

View file

@ -70,7 +70,7 @@ approval → executor → node-agent → docker restart → completed.
test E2E padł: agent rzucał `[Errno 13] Permission denied: test E2E padł: agent rzucał `[Errno 13] Permission denied:
/opt/homelab/actions/dispatch` co cykl. Root cause to ZNANY, POWRACAJĄCY /opt/homelab/actions/dispatch` co cykl. Root cause to ZNANY, POWRACAJĄCY
(już 4. raz — patrz sekcja "Tech-debt: globalny porządek uid/gid/uprawnień (już 4. raz — patrz sekcja "Tech-debt: globalny porządek uid/gid/uprawnień
we flocie" w `docs/backlog.md`) motyw we flocie" w `kb/phases/backlog.md`) motyw
uid/gid na PIHA: oskar ma uid 1004, kontener agenta biega jako uid 1000 uid/gid na PIHA: oskar ma uid 1004, kontener agenta biega jako uid 1000
(= user `pi` na hoście). `/opt/homelab/actions` było `oskar:oskar (= user `pi` na hoście). `/opt/homelab/actions` było `oskar:oskar
drwxr-xr-x` (utworzone w maju), podczas gdy DZIAŁAJĄCY wzorzec to drwxr-xr-x` (utworzone w maju), podczas gdy DZIAŁAJĄCY wzorzec to
@ -111,7 +111,7 @@ approval → executor → node-agent → docker restart → completed.
Pierwszy w historii systemu pełny cykl remediacji end-to-end potwierdzony w Pierwszy w historii systemu pełny cykl remediacji end-to-end potwierdzony w
produkcji (PIHA), bez SSH z control-plane do węzłów. Publiczna dziura produkcji (PIHA), bez SSH z control-plane do węzłów. Publiczna dziura
autoryzacji na `operator_ui.py:18180` zamknięta (bind ograniczony do autoryzacji na `operator_ui.py:18180` zamknięta (bind ograniczony do
Tailscale). Otwarte follow-upy — patrz `docs/backlog.md` (retry-w-nieskończoność Tailscale). Otwarte follow-upy — patrz `kb/phases/backlog.md` (retry-w-nieskończoność
zepsutego JSON, uprawnienia `actions/` na innych węzłach, brak twardego checka zepsutego JSON, uprawnienia `actions/` na innych węzłach, brak twardego checka
`.env`/`TAILSCALE_BIND_IP` w `deploy-local.sh`, brak autoryzacji w `.env`/`TAILSCALE_BIND_IP` w `deploy-local.sh`, brak autoryzacji w
`operator_ui.py`, zapchana approval queue przez `alert_only`, brak `operator_ui.py`, zapchana approval queue przez `alert_only`, brak

View file

@ -9,7 +9,7 @@ links: []
# Sesja 2026-07-23 — KB faza 4: ingress kb.kapala.org (krok 5/§8) # Sesja 2026-07-23 — KB faza 4: ingress kb.kapala.org (krok 5/§8)
**Zakres**: wyłącznie ingress (`docs/kb/modules/05-faza4-plan.md` §8, krok 5) — **Zakres**: wyłącznie ingress (`kb/phases/kb-m5-faza4.md` §8, krok 5) —
frontend i `/search` już LIVE na PIHA (port 8230) od sesji 2026-07-22. Zero frontend i `/search` już LIVE na PIHA (port 8230) od sesji 2026-07-22. Zero
zmian w kodzie kb-query w tej sesji. zmian w kodzie kb-query w tej sesji.
@ -70,8 +70,8 @@ w tej samej sesji, osobnym przebiegiem po zgłoszeniu przez operatora:
Potwierdzone w repo (zgodnie z `05-faza4-plan.md` §1.4): **brak wzorca Potwierdzone w repo (zgodnie z `05-faza4-plan.md` §1.4): **brak wzorca
forward-auth/reverse-proxy-level auth** — NPM community edition go nie ma forward-auth/reverse-proxy-level auth** — NPM community edition go nie ma
(sprawdzone: brak `oauth2-proxy`/`authelia`/`forward_auth` w kodzie repo poza (sprawdzone: brak `oauth2-proxy`/`authelia`/`forward_auth` w kodzie repo poza
wzmiankami "przyszła opcja" w `docs/kb/kb-02-documents-design.md` i wzmiankami "przyszła opcja" w `kb/subsystems/kb-documents-pillar.md` i
`hosts/vps/README.md`). Wszystkie 3 precedensy (paperless/nextcloud/vikunja) `kb/nodes/vps.md`). Wszystkie 3 precedensy (paperless/nextcloud/vikunja)
robią OIDC **wewnątrz aplikacji**. kb-query nie ma dziś żadnego logowania. robią OIDC **wewnątrz aplikacji**. kb-query nie ma dziś żadnego logowania.
Zgodnie z instrukcją zadania: **nie budowano** nowego komponentu auth. Zgodnie z instrukcją zadania: **nie budowano** nowego komponentu auth.
@ -122,7 +122,7 @@ username collision, `docs/sessions/2026-07-10-paperless-deploy.md`).
## Pliki repo zmienione ## Pliki repo zmienione
- `services/kb-query/README.md` — sekcja "Ingress" (co żyje, co nie, dlaczego - `kb/services/kb-query.md` — sekcja "Ingress" (co żyje, co nie, dlaczego
auth odłożone) zastępuje starą notatkę "not wired up yet". auth odłożone) zastępuje starą notatkę "not wired up yet".
- `docs/sessions/2026-07-23-kb-f4-ingress.md` — ten dokument. - `docs/sessions/2026-07-23-kb-f4-ingress.md` — ten dokument.

View file

@ -9,7 +9,7 @@ links: []
# Sesja 2026-07-27 — KB faza 4: fallback embed SOLARIA→PIHA (krok 3, ostatni element rdzenia) # Sesja 2026-07-27 — KB faza 4: fallback embed SOLARIA→PIHA (krok 3, ostatni element rdzenia)
> **Dopisek redakcyjny (2026-07-30, dedup — `docs/kb/modules/05-fallback-dedup-raport.md`):** > **Dopisek redakcyjny (2026-07-30, dedup — `kb/phases/kb-m5-faza4-fallback-dedup.md`):**
> implementacja kodu z tej sesji (`app/fallback.py`, branch `task/kb-f4-fallback`, 3d4ee38) > implementacja kodu z tej sesji (`app/fallback.py`, branch `task/kb-f4-fallback`, 3d4ee38)
> została **porzucona** — do mastera weszła równoległa, szersza implementacja tego samego > została **porzucona** — do mastera weszła równoległa, szersza implementacja tego samego
> kroku planu (e7625cd, `app/embed_router.py`, 2026-07-29) i to ona biega na PIHA. Ten log > kroku planu (e7625cd, `app/embed_router.py`, 2026-07-29) i to ona biega na PIHA. Ten log
@ -23,7 +23,7 @@ links: []
> Z delty brancha uratowano ponadto: `retrieval_eval.py --transport http` (plan §2 D6/§9) > Z delty brancha uratowano ponadto: `retrieval_eval.py --transport http` (plan §2 D6/§9)
> i luki testowe T1/T2 przeniesione do `test_embed_router.py`. > i luki testowe T1/T2 przeniesione do `test_embed_router.py`.
**Zakres**: `docs/kb/modules/05-faza4-plan.md` §2 decyzja 2 / §5 — aktywny fallback **Zakres**: `kb/phases/kb-m5-faza4.md` §2 decyzja 2 / §5 — aktywny fallback
embedu, ostatni brakujący element rdzenia fazy 4 (frontend i ingress LIVE od embedu, ostatni brakujący element rdzenia fazy 4 (frontend i ingress LIVE od
2026-07-22/23, `docs/sessions/2026-07-23-kb-f4-ingress.md`). Zero zmian w schemacie 2026-07-22/23, `docs/sessions/2026-07-23-kb-f4-ingress.md`). Zero zmian w schemacie
DB, zero zmian w `kb_retrieval`'s retrieval logice — wyłącznie warstwa embed + health. DB, zero zmian w `kb_retrieval`'s retrieval logice — wyłącznie warstwa embed + health.

View file

@ -19,8 +19,8 @@ e8aa3e3 docs(architecture): recon multiagent 2026-07-27
### Files changed ### Files changed
``` ```
docs/architecture/PLAN-subsystem-a-2026-07-28.md | 60 +++ kb/phases/subsystem-a-naprawa.md | 60 +++
docs/architecture/RECON-multiagent-2026-07-27.md | 551 +++++++++++++++++++++++ kb/subsystems/recon-multiagent.md | 551 +++++++++++++++++++++++
2 files changed, 611 insertions(+) 2 files changed, 611 insertions(+)
``` ```

View file

@ -22,7 +22,7 @@ pilota fazy 5 (narty27), wykonanego równolegle.
- session log 27.07 - session log 27.07
- testy luk T1T3 - testy luk T1T3
- komentarz kalibracji progów dist. - komentarz kalibracji progów dist.
- Pełny rozbiór obu implementacji: `docs/kb/modules/05-fallback-dedup-raport.md`. - Pełny rozbiór obu implementacji: `kb/phases/kb-m5-faza4-fallback-dedup.md`.
### Deploy na PIHA (z mastera) ### Deploy na PIHA (z mastera)
- `ollama-piha`: named volume `ollama_piha_models`, model bge-m3, `KEEP_ALIVE=0`. - `ollama-piha`: named volume `ollama_piha_models`, model bge-m3, `KEEP_ALIVE=0`.
@ -76,7 +76,7 @@ infry**. Infra: `services/narty27`.
stubie nie przechodzi wyłącznie z tego powodu. stubie nie przechodzi wyłącznie z tego powodu.
2. **`hosts/solaria/runtime/ollama/docker-compose.override.yml` — brak w repo** 2. **`hosts/solaria/runtime/ollama/docker-compose.override.yml` — brak w repo**
(rozjazd repo↔runtime na SOLARII). (rozjazd repo↔runtime na SOLARII).
3. **R1R3 node-agent** (incydent `docs/incidents/2026-07-30-ollama-solaria-vanish.md`) 3. **R1R3 node-agent** (incydent `kb/incidents/2026-07-30-ollama-solaria-vanish.md`)
**niezrobione**: R1 `_prune_stopped_containers` nie może kasować kontenerów **niezrobione**: R1 `_prune_stopped_containers` nie może kasować kontenerów
zarządzanych, R2 rate-limit dla `ai_node`/`standard`, R3 logowanie usuniętych zarządzanych, R2 rate-limit dla `ai_node`/`standard`, R3 logowanie usuniętych
zasobów. Przyczyna nadal aktywna → blokuje/warunkuje fazę mailową zasobów. Przyczyna nadal aktywna → blokuje/warunkuje fazę mailową

View file

@ -1,6 +1,6 @@
# PIHA-specific override for node_exporter. # PIHA-specific override for node_exporter.
# #
# WHY: KB module 5 phase 3 step 5 (docs/kb/modules/05-faza3-plan.md §7.2) needs the # WHY: KB module 5 phase 3 step 5 (kb/phases/kb-m5-faza3.md §7.2) needs the
# textfile collector so kb-ingest's systemd timer can publish # textfile collector so kb-ingest's systemd timer can publish
# kb_ingest_last_success_timestamp / kb_ingest_last_exit_code / kb_ingest_embed_backlog # kb_ingest_last_success_timestamp / kb_ingest_last_exit_code / kb_ingest_embed_backlog
# etc. for fleet-prometheus to scrape and alert on. # etc. for fleet-prometheus to scrape and alert on.

View file

@ -84,7 +84,7 @@ services:
external: [] external: []
runtime: runtime:
# textfile collector reads /opt/homelab/state/node-exporter (module 5 phase 3 step 5, # textfile collector reads /opt/homelab/state/node-exporter (module 5 phase 3 step 5,
# docs/kb/modules/05-faza3-plan.md §7.2 — kb-ingest.prom) via the existing /:/host:ro # kb/phases/kb-m5-faza3.md §7.2 — kb-ingest.prom) via the existing /:/host:ro
# mount, see hosts/piha/runtime/node_exporter/docker-compose.override.yml. # mount, see hosts/piha/runtime/node_exporter/docker-compose.override.yml.
data_path: /opt/homelab/state/node-exporter data_path: /opt/homelab/state/node-exporter
@ -161,7 +161,7 @@ services:
runtime: runtime:
# No config and no secrets. Content is PERSONAL and deliberately outside # No config and no secrets. Content is PERSONAL and deliberately outside
# the repo — it lives only in the Docker named volume # the repo — it lives only in the Docker named volume
# narty27_narty27_content, refreshed from SOLARIA (services/narty27/README.md). # narty27_narty27_content, refreshed from SOLARIA (kb/runbooks/narty27-deploy.md).
# No backup job, no /opt/homelab/data bind. # No backup job, no /opt/homelab/data bind.
config_path: services/narty27 config_path: services/narty27

View file

@ -1,7 +1,7 @@
# MITYGACJA TYMCZASOWA (M1) — założona 2026-08-04. # MITYGACJA TYMCZASOWA (M1) — założona 2026-08-04.
# NODE_TYPE=lte_node wyłącza run_safe_cleanup() (niefiltrowany # NODE_TYPE=lte_node wyłącza run_safe_cleanup() (niefiltrowany
# `docker container prune`) na czas backfillu embed (faza mailowa KB). # `docker container prune`) na czas backfillu embed (faza mailowa KB).
# Incydent: docs/incidents/2026-07-30-ollama-solaria-vanish.md (§7, M1). # Incydent: kb/incidents/2026-07-30-ollama-solaria-vanish.md (§7, M1).
# Bez tego każdy zatrzymany kontener na SOLARII znika w ≤60 s — również taki # Bez tego każdy zatrzymany kontener na SOLARII znika w ≤60 s — również taki
# z `restart: unless-stopped`, zatrzymany świadomie przez operatora. # z `restart: unless-stopped`, zatrzymany świadomie przez operatora.
# Warunek zdjęcia: R1 (filtrowanie prune po restart policy / labelu compose) # Warunek zdjęcia: R1 (filtrowanie prune po restart policy / labelu compose)

View file

@ -167,5 +167,5 @@ services:
# redis, mosquitto): legacy stack, runs UNMANAGED on vps and is scheduled # redis, mosquitto): legacy stack, runs UNMANAGED on vps and is scheduled
# for retirement — its codex/* bus has been idle since 2026-06-09. # for retirement — its codex/* bus has been idle since 2026-06-09.
# Deliberately NO entry here: legacy is not pulled into desired state. # Deliberately NO entry here: legacy is not pulled into desired state.
# See docs/architecture/ai-cluster-LEGACY.md and # See kb/decisions/ai-cluster-legacy.md and
# docs/architecture/RECON-multiagent-2026-07-27.md (C9). # kb/subsystems/recon-multiagent.md (C9).

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# jobs/deploy-runner/deploy-runner.sh — host-side executor for `redeploy` actions. # jobs/deploy-runner/deploy-runner.sh — host-side executor for `redeploy` actions.
# #
# WHY THIS EXISTS (docs/architecture/RECON-multiagent-2026-07-27.md D14/D15): # WHY THIS EXISTS (kb/subsystems/recon-multiagent.md D14/D15):
# the control-plane executor could never carry out a redeploy — it ran # the control-plane executor could never carry out a redeploy — it ran
# deploy-node.sh inside its own container, a script that ignores its arguments # deploy-node.sh inside its own container, a script that ignores its arguments
# and expects a repo at ${HOME}/homelab-codex-ws that does not exist there (nor # and expects a repo at ${HOME}/homelab-codex-ws that does not exist there (nor
@ -9,7 +9,7 @@
# dead-ended, which is the single biggest reason the self-healing loop had # dead-ended, which is the single biggest reason the self-healing loop had
# 18 pending / 0 completed actions. # 18 pending / 0 completed actions.
# #
# The fix keeps the architecture decision from docs/backlog.md ("Remediacja # The fix keeps the architecture decision from kb/phases/backlog.md ("Remediacja
# floty bez SSH"): the VPS never initiates a connection to a node. The executor # floty bez SSH"): the VPS never initiates a connection to a node. The executor
# only WRITES an action file; this runner, on the target node, pulls it, runs # only WRITES an action file; this runner, on the target node, pulls it, runs
# the deploy locally, and reports the outcome back through the existing event # the deploy locally, and reports the outcome back through the existing event

View file

@ -1,6 +1,6 @@
# Eval-set for the retrieval quality gate (module 5, phase 3, plan §6.2, # Eval-set for the retrieval quality gate (module 5, phase 3, plan §6.2,
# docs/kb/modules/05-faza3-plan.md). Transcribed 1:1 from the pilot baseline, # kb/phases/kb-m5-faza3.md). Transcribed 1:1 from the pilot baseline,
# docs/kb/eval/retrieval-pilot-2026-07-16.md (read-only source -- this file is the versioned # kb/phases/kb-m5-eval-retrieval-pilot.md (read-only source -- this file is the versioned
# copy the plan asked for, so the set stops living only in a session transcript). # copy the plan asked for, so the set stops living only in a session transcript).
# #
# kind: # kind:
@ -80,7 +80,7 @@ queries:
wpis, patrz historia sesji). Próg tej kontroli obniżony do 0.50 (z 0.55) właśnie z powodu wpis, patrz historia sesji). Próg tej kontroli obniżony do 0.50 (z 0.55) właśnie z powodu
tej znanej kolizji, żeby bramka nie płonęła co uruchomienie na nie-problemie. tej znanej kolizji, żeby bramka nie płonęła co uruchomienie na nie-problemie.
# Faza mailowa (docs/kb/modules/05-faza-mailowa-plan.md, §8, Krok 5) -- bramka jakościowa dla # Faza mailowa (kb/phases/kb-m5-faza-mailowa.md, §8, Krok 5) -- bramka jakościowa dla
# treści mailowej wprowadzonej w Etapie A (ostatnie 12 miesięcy, plan §7 Krok 4). Wypełniona # treści mailowej wprowadzonej w Etapie A (ostatnie 12 miesięcy, plan §7 Krok 4). Wypełniona
# przez operatora 2026-07-23 (5 zapytań "wiem że to mam w mailach z ostatniego roku"; M5 # przez operatora 2026-07-23 (5 zapytań "wiem że to mam w mailach z ostatniego roku"; M5
# odrzucone po weryfikacji, patrz N2 powyżej i historia sesji). expected_envelope celowo null # odrzucone po weryfikacji, patrz N2 powyżej i historia sesji). expected_envelope celowo null

View file

@ -1,5 +1,5 @@
"""Retrieval quality gate -- module 5, phase 3, plan §6.2 (docs/kb/modules/05-faza3-plan.md), """Retrieval quality gate -- module 5, phase 3, plan §6.2 (kb/phases/kb-m5-faza3.md),
extended in faza mailowa Krok 5 (docs/kb/modules/05-faza-mailowa-plan.md, §8) to add the extended in faza mailowa Krok 5 (kb/phases/kb-m5-faza-mailowa.md, §8) to add the
`hybrid` track once mail content exists in `document_chunk` (faza mailowa Krok 2/4). `hybrid` track once mail content exists in `document_chunk` (faza mailowa Krok 2/4).
Read-only integration script (NOT collected by pytest -- it hits the live kb-postgres DB and Read-only integration script (NOT collected by pytest -- it hits the live kb-postgres DB and
@ -343,7 +343,7 @@ def print_report(
rows: list[dict], n_values: list[int], gate_result: dict, mail_rows: Optional[list[dict]] = None rows: list[dict], n_values: list[int], gate_result: dict, mail_rows: Optional[list[dict]] = None
) -> None: ) -> None:
print("=" * 100) print("=" * 100)
print("RETRIEVAL QUALITY GATE -- plan §6.2 (docs/kb/modules/05-faza3-plan.md), " print("RETRIEVAL QUALITY GATE -- plan §6.2 (kb/phases/kb-m5-faza3.md), "
"+ hybrid/mail extension (05-faza-mailowa-plan.md §8)") "+ hybrid/mail extension (05-faza-mailowa-plan.md §8)")
print("=" * 100) print("=" * 100)
header = f"{'id':<3} {'kind':<28} {'expected':<16} {'flat d1':>8} {'flat@3':>7}" header = f"{'id':<3} {'kind':<28} {'expected':<16} {'flat d1':>8} {'flat@3':>7}"

View file

@ -1,8 +1,8 @@
"""Chunk + embed job — module 5 phase 2, plan step 6 (docs/kb/modules/05-faza2-plan.md, """Chunk + embed job — module 5 phase 2, plan step 6 (kb/phases/kb-m5-faza2.md,
§6 step 6, decision 3). §6 step 6, decision 3).
`chunk_text`/`hard_split`/`split_paragraphs`/`TARGET_CHARS`/`OVERLAP_CHARS` moved to `chunk_text`/`hard_split`/`split_paragraphs`/`TARGET_CHARS`/`OVERLAP_CHARS` moved to
`kb_mail.chunking` in module 5 faza mailowa, Krok 0 (docs/kb/modules/05-faza-mailowa-plan.md, §3) `kb_mail.chunking` in module 5 faza mailowa, Krok 0 (kb/phases/kb-m5-faza-mailowa.md, §3)
so `jobs/mail-body-ingest` shares the exact same chunker instead of a copy-pasted drift; re-exported so `jobs/mail-body-ingest` shares the exact same chunker instead of a copy-pasted drift; re-exported
here unchanged so nothing importing them from this module breaks. here unchanged so nothing importing them from this module breaks.
@ -23,7 +23,7 @@ Install (from repo root):
pip install -e jobs/documents-ingest/ pip install -e jobs/documents-ingest/
`embed_chunk`/`_vector_literal`/`DEFAULT_MODEL`/`DEFAULT_OLLAMA_URL` moved to `embed_chunk`/`_vector_literal`/`DEFAULT_MODEL`/`DEFAULT_OLLAMA_URL` moved to
`kb_retrieval.embed` in module 5 phase 4 (docs/kb/modules/05-faza4-plan.md, §3, decision 1) so `kb_retrieval.embed` in module 5 phase 4 (kb/phases/kb-m5-faza4.md, §3, decision 1) so
`kb-query` (Docker service) can share the same client without pulling in this job's `anthropic` `kb-query` (Docker service) can share the same client without pulling in this job's `anthropic`
dependency; re-exported here unchanged so nothing importing them from this module breaks. dependency; re-exported here unchanged so nothing importing them from this module breaks.

View file

@ -1,4 +1,4 @@
"""Cyclic ingest wrapper -- module 5 phase 3, plan step 5 (docs/kb/modules/05-faza3-plan.md, """Cyclic ingest wrapper -- module 5 phase 3, plan step 5 (kb/phases/kb-m5-faza3.md,
§7). Orchestrates one run of the recurring ingest pipeline for `kb-ingest.timer` on PIHA: §7). Orchestrates one run of the recurring ingest pipeline for `kb-ingest.timer` on PIHA:
paperless_adapter.run() -- new source='paperless' envelopes paperless_adapter.run() -- new source='paperless' envelopes

View file

@ -1,6 +1,6 @@
"""PDF attachment extractor — kb-postgres mail archive -> Paperless consume/. """PDF attachment extractor — kb-postgres mail archive -> Paperless consume/.
Module 5 ("documents-ingest"), Phase 1 (docs/kb/modules/05-documents-ingest.md, Module 5 ("documents-ingest"), Phase 1 (kb/phases/kb-m5-documents-ingest.md,
section "Domkniecie dlugu z maili"): pull a sample of PDF attachments out of the section "Domkniecie dlugu z maili"): pull a sample of PDF attachments out of the
Gmail .eml archive and drop them into Paperless' consume/ dir so Paperless does Gmail .eml archive and drop them into Paperless' consume/ dir so Paperless does
the OCR + correspondent-detection. This is NOT the Paperless/Nextcloud envelope the OCR + correspondent-detection. This is NOT the Paperless/Nextcloud envelope

View file

@ -1,4 +1,4 @@
"""Paperless -> envelope adapter — module 5 phase 2 (docs/kb/modules/05-faza2-plan.md, """Paperless -> envelope adapter — module 5 phase 2 (kb/phases/kb-m5-faza2.md,
§4.2-4.3, §6 step 5). §4.2-4.3, §6 step 5).
Reads documents from the Paperless REST API (read-only GET only, this job never Reads documents from the Paperless REST API (read-only GET only, this job never

View file

@ -1,5 +1,5 @@
"""Re-export shim -- the retrieval module moved to `packages/kb-retrieval/` in module 5 phase """Re-export shim -- the retrieval module moved to `packages/kb-retrieval/` in module 5 phase
4 (docs/kb/modules/05-faza4-plan.md, §3, decision 1) so both this job and `kb-query` (Docker 4 (kb/phases/kb-m5-faza4.md, §3, decision 1) so both this job and `kb-query` (Docker
service) share one tested module. Kept here unchanged so nothing importing service) share one tested module. Kept here unchanged so nothing importing
`documents_ingest.retrieval` breaks; new code should import `kb_retrieval.retrieval` directly. `documents_ingest.retrieval` breaks; new code should import `kb_retrieval.retrieval` directly.
""" """

View file

@ -1,4 +1,4 @@
"""Summarize + tag job — module 5 phase 3, plan step 3 (docs/kb/modules/05-faza3-plan.md, """Summarize + tag job — module 5 phase 3, plan step 3 (kb/phases/kb-m5-faza3.md,
§5 step 3, §2 decision 3: two-track A/B pilot). §5 step 3, §2 decision 3: two-track A/B pilot).
Pipeline: `document_chunk.text WHERE excluded_reason IS NULL ORDER BY chunk_index` per Pipeline: `document_chunk.text WHERE excluded_reason IS NULL ORDER BY chunk_index` per

View file

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# kb-ingest-run.sh — thin launcher for kb-ingest.service (module 5 phase 3 step 5, # kb-ingest-run.sh — thin launcher for kb-ingest.service (module 5 phase 3 step 5,
# docs/kb/modules/05-faza3-plan.md §7.1). # kb/phases/kb-m5-faza3.md §7.1).
# #
# All sequencing/tolerance/exit-code logic lives in documents-ingest-cyclic (Python, # All sequencing/tolerance/exit-code logic lives in documents-ingest-cyclic (Python,
# jobs/documents-ingest/src/documents_ingest/cyclic_ingest.py) — this script only computes # jobs/documents-ingest/src/documents_ingest/cyclic_ingest.py) — this script only computes

View file

@ -49,8 +49,8 @@ class TestVectorLiteral:
class TestIsOcrJunk: class TestIsOcrJunk:
"""Pilot cases from docs/kb/modules/05-faza3-plan.md §3.1 and the 2026-07-16 calibration """Pilot cases from kb/phases/kb-m5-faza3.md §3.1 and the 2026-07-16 calibration
session (docs/kb/eval/retrieval-pilot-2026-07-16.md).""" session (kb/phases/kb-m5-eval-retrieval-pilot.md)."""
def test_clean_text_is_not_junk(self): def test_clean_text_is_not_junk(self):
text = ( text = (

View file

@ -1,4 +1,4 @@
"""Gmail header backfill — one-shot job, module 5 phase 2 (docs/kb/modules/05-faza2-plan.md, §5). """Gmail header backfill — one-shot job, module 5 phase 2 (kb/phases/kb-m5-faza2.md, §5).
Backfills `{"type": "headers", ...}` (§4.1) onto the 225 030 existing `source='gmail'` Backfills `{"type": "headers", ...}` (§4.1) onto the 225 030 existing `source='gmail'`
envelope rows in kb-postgres, which today carry only an attachment manifest. This is an envelope rows in kb-postgres, which today carry only an attachment manifest. This is an

View file

@ -1,5 +1,5 @@
"""Mail body ingest job — module 5, faza mailowa, plan Krok 2 """Mail body ingest job — module 5, faza mailowa, plan Krok 2
(docs/kb/modules/05-faza-mailowa-plan.md, §5). Second full pass over the gmail .eml archive (kb/phases/kb-m5-faza-mailowa.md, §5). Second full pass over the gmail .eml archive
(the first was gmail-bulk-import's manifest-only import): extracts inline body text that (the first was gmail-bulk-import's manifest-only import): extracts inline body text that
`_parse_attachments` deliberately skipped, chunks it, embeds it (batched), and appends `_parse_attachments` deliberately skipped, chunks it, embeds it (batched), and appends
`entities[type=threading]` the only new writes are `document_chunk` INSERTs and an additive `entities[type=threading]` the only new writes are `document_chunk` INSERTs and an additive

View file

@ -10,7 +10,7 @@ links: []
# Recon — node-agent vs stability-agent (2026-07-30) # Recon — node-agent vs stability-agent (2026-07-30)
Read-only recon. Ground truth: `docs/architecture/RECON-multiagent-2026-07-27.md` Read-only recon. Ground truth: `kb/subsystems/recon-multiagent.md`
(A1, A2, B7, D15). Source read at master @ `473bf8e`; this branch is cut from (A1, A2, B7, D15). Source read at master @ `473bf8e`; this branch is cut from
master @ `0650eb8`. The two intervening merges (`0650eb8` ha-mcp, `cb8a19d` master @ `0650eb8`. The two intervening merges (`0650eb8` ha-mcp, `cb8a19d`
kb-query tests) touch none of the audited paths — `services/node-agent/`, kb-query tests) touch none of the audited paths — `services/node-agent/`,
@ -66,7 +66,7 @@ control plane, stability-agent feeds the agent-system UI, and stability-agent's
half of the event store is a write-only archive nothing has ever read. half of the event store is a write-only archive nothing has ever read.
A prior recon reached the same conclusion about the event path on 2026-07-06 A prior recon reached the same conclusion about the event path on 2026-07-06
(`docs/infra/prometheus-cutover-recon-2026-07-06.md:88-91`); it has not been acted on. (`kb/audits/prometheus-cutover-2026-07-06.md:88-91`); it has not been acted on.
--- ---
@ -307,7 +307,7 @@ prefix that `container_service_name()` was written to strip.
- Remove entries from `hosts/solaria/services.yaml` and `hosts/vps/services.yaml`. - Remove entries from `hosts/solaria/services.yaml` and `hosts/vps/services.yaml`.
- `docker compose down` on vps, piha, solaria (chelsty-infra when reachable). - `docker compose down` on vps, piha, solaria (chelsty-infra when reachable).
- Purge or archive `/opt/homelab/events/2026-*/` on all four nodes (~5 MB on piha, mostly May). - Purge or archive `/opt/homelab/events/2026-*/` on all four nodes (~5 MB on piha, mostly May).
- Update CLAUDE.md (agent-system architecture §1, event-path claim at line 100), `docs/chelsty-stability-agent.md`, recon A1/A2/B7. - Update CLAUDE.md (agent-system architecture §1, event-path claim at line 100), `kb/services/chelsty-stability-agent.md`, recon A1/A2/B7.
- **Not covered by the cleanup:** the Redis publisher must be rehomed first or the UI loss is permanent. - **Not covered by the cleanup:** the Redis publisher must be rehomed first or the UI loss is permanent.
### (b) Merge stability-agent's unique checks into node-agent ### (b) Merge stability-agent's unique checks into node-agent

View file

@ -131,7 +131,7 @@ compose-service kontenera.
| owntracks-prometheus-exporter-prometheus-owntracks-exporter-1 | linusgroh/prometheus-owntracks-exporter | Up 2w | 0.0.0.0:8780→80 | | owntracks-prometheus-exporter-prometheus-owntracks-exporter-1 | linusgroh/prometheus-owntracks-exporter | Up 2w | 0.0.0.0:8780→80 |
| own-tracks-frontend-owntracks-frontend-1 | owntracks/frontend | Up 2w | 0.0.0.0:8084→80 | | own-tracks-frontend-owntracks-frontend-1 | owntracks/frontend | Up 2w | 0.0.0.0:8084→80 |
Zmiany vs audyt 2026-06-30 (`docs/infra/inventory-2026-06-30.md`): **przybyły** paperless, Zmiany vs audyt 2026-06-30 (`kb/subsystems/fleet-inventory.md`): **przybyły** paperless,
paperless-db, paperless-broker (Deploy 1, 2026-07-10); **zniknęły** diskover i elasticsearch paperless-db, paperless-broker (Deploy 1, 2026-07-10); **zniknęły** diskover i elasticsearch
(w audycie 06-30 były w 33 shadow; dziś nie biegają). 06-30: 40 kontenerów → dziś: 42. (w audycie 06-30 były w 33 shadow; dziś nie biegają). 06-30: 40 kontenerów → dziś: 42.

View file

@ -10,7 +10,7 @@ links: []
# Audyt odchudzania PIHA — 2026-07-02 # Audyt odchudzania PIHA — 2026-07-02
> Faza 1 (READ-ONLY) modulu 0 filaru dokumentow (`docs/kb/modules/00-piha-slim.md`). > Faza 1 (READ-ONLY) modulu 0 filaru dokumentow (`kb/phases/kb-m0-piha-slim.md`).
> Zadna akcja nie zostala wykonana — wylacznie `docker stats/inspect/logs`, `ss`, `curl` (odczyt). > Zadna akcja nie zostala wykonana — wylacznie `docker stats/inspect/logs`, `ss`, `curl` (odczyt).
> Stan w momencie audytu: **RAM 7.9Gi total, 5.0Gi used, 2.9Gi available; swap 4Gi total, 2.0Gi uzyty.** > Stan w momencie audytu: **RAM 7.9Gi total, 5.0Gi used, 2.9Gi available; swap 4Gi total, 2.0Gi uzyty.**
> 41 kontenerow Up (inwentaryzacja 2026-06-30 liczyla 40; wszystkie nadal biega). > 41 kontenerow Up (inwentaryzacja 2026-06-30 liczyla 40; wszystkie nadal biega).

View file

@ -300,7 +300,7 @@ renderuje `health`/`status`/`last_seen`), `/unhealthy` (`:302-334`), `/summary`,
chelsty/chelsty-infra (exporter DOWN po LTE, 2026-06-26). chelsty/chelsty-infra (exporter DOWN po LTE, 2026-06-26).
- Reguła `NodeDown` (`rules/liveness.yml:21-28`): `up{node=~"vps|piha"} == 0`, - Reguła `NodeDown` (`rules/liveness.yml:21-28`): `up{node=~"vps|piha"} == 0`,
`for: 5m`, severity critical. solaria/lustro świadomie wykluczone (`:12-16` — `for: 5m`, severity critical. solaria/lustro świadomie wykluczone (`:12-16` —
planned power-off; docelowo anomaly detection, `docs/backlog.md:390-406`). planned power-off; docelowo anomaly detection, `kb/phases/backlog.md:390-406`).
Bez Alertmanagera by design (`:3-7`) — delivery = brain-watchdog poll `/api/v1/alerts`. Bez Alertmanagera by design (`:3-7`) — delivery = brain-watchdog poll `/api/v1/alerts`.
- node_exporter w repo tylko dla VPS (`services/node_exporter/`, network_mode: host, - node_exporter w repo tylko dla VPS (`services/node_exporter/`, network_mode: host,
`hosts/vps/services.yaml:36-43`). Exportery na piha/solaria/lustro **nie mają `hosts/vps/services.yaml:36-43`). Exportery na piha/solaria/lustro **nie mają
@ -348,7 +348,7 @@ chelsty-infra, chelsty-ha, lustro.
| lustro | TAK (`:50-52`) | NIE | TAK (bez stability-agenta) | jw. | | lustro | TAK (`:50-52`) | NIE | TAK (bez stability-agenta) | jw. |
| **chelsty-infra** | **NIE** (`:57-60`, exporter DOWN po LTE) | NIE | **TAK** (remote TTL 900/3600, `liveness.py:43-50`) | **tylko stary tor — cutover totalny zostawiłby go bez liveności** | | **chelsty-infra** | **NIE** (`:57-60`, exporter DOWN po LTE) | NIE | **TAK** (remote TTL 900/3600, `liveness.py:43-50`) | **tylko stary tor — cutover totalny zostawiłby go bez liveności** |
| chelsty-ha | NIE | NIE | NIE (`hosts/chelsty-ha/services.yaml:6-12`, `monitor: false`) | już dziś bez liveności (pośrednio przez MQTT chelsty-infra) — cutover nic nie zmienia | | chelsty-ha | NIE | NIE | NIE (`hosts/chelsty-ha/services.yaml:6-12`, `monitor: false`) | już dziś bez liveności (pośrednio przez MQTT chelsty-infra) — cutover nic nie zmienia |
| saturn | NIE (`:55`, laptop) | NIE | NIE (brak `hosts/saturn/services.yaml`, `docs/backlog.md:423`) | już dziś bez liveności — cutover nic nie zmienia | | saturn | NIE (`:55`, laptop) | NIE | NIE (brak `hosts/saturn/services.yaml`, `kb/phases/backlog.md:423`) | już dziś bez liveności — cutover nic nie zmienia |
**Chelsty offline ~34 dni — jak traktuje go stara rura:** eventy buforują się lokalnie **Chelsty offline ~34 dni — jak traktuje go stara rura:** eventy buforują się lokalnie
(rsync fail = non-fatal, `node_agent.py:560-566`), `last_seen` na VPS zamrożone sprzed (rsync fail = non-fatal, `node_agent.py:560-566`), `last_seen` na VPS zamrożone sprzed
@ -361,7 +361,7 @@ totalnym chelsty-infra nie miałby żadnej liveności i żadnego przejścia offl
Dodatkowo docs sygnalizują konflikt IP w komentarzach `prometheus.yml:57` vs Dodatkowo docs sygnalizują konflikt IP w komentarzach `prometheus.yml:57` vs
`hosts/chelsty-infra/host.yaml:12` — do wyjaśnienia przy ewentualnym dodawaniu scrape. `hosts/chelsty-infra/host.yaml:12` — do wyjaśnienia przy ewentualnym dodawaniu scrape.
*(rzeczywisty bieżący stan chelsty — do weryfikacji na żywo; ostatni zapis: *(rzeczywisty bieżący stan chelsty — do weryfikacji na żywo; ostatni zapis:
UNREACHABLE, `docs/infra/inventory-verify-2026-07-02.md:17,151`)* UNREACHABLE, `kb/subsystems/fleet-inventory-verify.md:17,151`)*
**Wniosek twardy:** cutover NIE może być globalny. Docelowa architektura to **Wniosek twardy:** cutover NIE może być globalny. Docelowa architektura to
**hybryda per-node**: `up{}` dla scrape'owanych (vps, piha, solaria, lustro), **hybryda per-node**: `up{}` dla scrape'owanych (vps, piha, solaria, lustro),
@ -460,7 +460,7 @@ z `last_seen` — rzadszy heartbeat przy niezmienionych TTL-ach = fałszywe degr
- chelsty-infra: zbadać exporter-over-LTE (`prometheus.yml:57-60` + konflikt IP - chelsty-infra: zbadać exporter-over-LTE (`prometheus.yml:57-60` + konflikt IP
z `hosts/chelsty-infra/host.yaml:12`); do tego czasu zostaje na torze eventowym. z `hosts/chelsty-infra/host.yaml:12`); do tego czasu zostaje na torze eventowym.
- NodeDown dla solaria/lustro: świadomie odroczone do anomaly detection - NodeDown dla solaria/lustro: świadomie odroczone do anomaly detection
(`docs/backlog.md:390-406`) — nie wciągać do cutoveru. (`kb/phases/backlog.md:390-406`) — nie wciągać do cutoveru.
- Watchdog na sam Prometheus (D.2 pkt 5) — mały task przy etapie 3. - Watchdog na sam Prometheus (D.2 pkt 5) — mały task przy etapie 3.
- saturn / chelsty-ha: świadomie poza monitoringiem — status quo. - saturn / chelsty-ha: świadomie poza monitoringiem — status quo.
@ -468,7 +468,7 @@ z `last_seen` — rzadszy heartbeat przy niezmienionych TTL-ach = fałszywe degr
**Seria.** Minimalnie trzy taski implementacyjne + weryfikacje między nimi: **Seria.** Minimalnie trzy taski implementacyjne + weryfikacje między nimi:
(1) etap 1 shadow-read; (2) etap 3 flaga per-node (po tygodniu etapu 2); (1) etap 1 shadow-read; (2) etap 3 flaga per-node (po tygodniu etapu 2);
(3) watchdog-na-Prometheusa + aktualizacja `docs/observer-runtime.md`. (3) watchdog-na-Prometheusa + aktualizacja `kb/subsystems/observer.md`.
Etap 0 to czynność operatorska (runtime, nie repo). Etap 5 to niezależny backlog. Etap 0 to czynność operatorska (runtime, nie repo). Etap 5 to niezależny backlog.
--- ---

View file

@ -14,7 +14,7 @@ links: []
Stack **ai-cluster** działający na vps (`ai-cluster-openclaw-1`, `codex-worker`, Stack **ai-cluster** działający na vps (`ai-cluster-openclaw-1`, `codex-worker`,
`planner-worker`, `service-ops-worker`, `redis`, `mosquitto`) jest **wygaszany, `planner-worker`, `service-ops-worker`, `redis`, `mosquitto`) jest **wygaszany,
nie migrowany**. Podstawa (recon nie migrowany**. Podstawa (recon
[RECON-multiagent-2026-07-27.md](RECON-multiagent-2026-07-27.md), C9): [RECON-multiagent-2026-07-27.md](../subsystems/recon-multiagent.md), C9):
bus `codex/*` jest martwy od **2026-06-09** — zero nowych połączeń przez ~7 tygodni, bus `codex/*` jest martwy od **2026-06-09** — zero nowych połączeń przez ~7 tygodni,
workery trzymają tylko puste długożyjące połączenia. workery trzymają tylko puste długożyjące połączenia.

View file

@ -10,8 +10,8 @@ links: []
# Architektura — decyzje obowiązujące # Architektura — decyzje obowiązujące
Stan decyzji na 2026-07-28. Podstawa dowodowa: Stan decyzji na 2026-07-28. Podstawa dowodowa:
[RECON-multiagent-2026-07-27.md](RECON-multiagent-2026-07-27.md); plan wykonawczy: [RECON-multiagent-2026-07-27.md](../subsystems/recon-multiagent.md); plan wykonawczy:
[PLAN-subsystem-a-2026-07-28.md](PLAN-subsystem-a-2026-07-28.md). Zmiana którejkolwiek [PLAN-subsystem-a-2026-07-28.md](../phases/subsystem-a-naprawa.md). Zmiana którejkolwiek
decyzji wymaga aktualizacji tego pliku z nową datą. decyzji wymaga aktualizacji tego pliku z nową datą.
## Dwa subsystemy (2026-07-28) ## Dwa subsystemy (2026-07-28)
@ -42,7 +42,7 @@ Stack ai-cluster na vps (openclaw, codex-worker, planner-worker, service-ops-wor
redis, mosquitto) jest **wygaszany, nie migrowany**. Bus `codex/*` martwy od redis, mosquitto) jest **wygaszany, nie migrowany**. Bus `codex/*` martwy od
2026-06-09 (zero nowych połączeń). Branch `task/ai-cluster-solaria` zostaje 2026-06-09 (zero nowych połączeń). Branch `task/ai-cluster-solaria` zostaje
**niezmergowany** — pełni rolę dokumentacji. Kontenery na vps zostaną zatrzymane w **niezmergowany** — pełni rolę dokumentacji. Kontenery na vps zostaną zatrzymane w
osobnej, nadzorowanej sesji. Szczegóły: [ai-cluster-LEGACY.md](ai-cluster-LEGACY.md). osobnej, nadzorowanej sesji. Szczegóły: [ai-cluster-LEGACY.md](ai-cluster-legacy.md).
## Approvale zostają HITL (2026-07-28) ## Approvale zostają HITL (2026-07-28)

View file

@ -54,7 +54,7 @@ z repo daje kontener identyczny z obecnym **zanim** ktokolwiek zrobi redeploy.
znalezione przy porządkowaniu backlogu po tej sesji znalezione przy porządkowaniu backlogu po tej sesji
**Problem**: kontrakt serwisu deklaruje `private``services/narty27/service.yaml:5` **Problem**: kontrakt serwisu deklaruje `private``services/narty27/service.yaml:5`
(`exposure: private # LAN/Tailscale only; no npm vhost, no public ingress`) i to samo (`exposure: private # LAN/Tailscale only; no npm vhost, no public ingress`) i to samo
w `services/narty27/README.md` — podczas gdy `narty27.kapala.org` jest **publiczne** w `kb/runbooks/narty27-deploy.md` — podczas gdy `narty27.kapala.org` jest **publiczne**
(NPM na VPS + cert Let's Encrypt). Pole `exposure` steruje traktowaniem ekspozycji (NPM na VPS + cert Let's Encrypt). Pole `exposure` steruje traktowaniem ekspozycji
przez agentów (patrz „Discovery Entry Points for Agents" w CLAUDE.md — `service.yaml` przez agentów (patrz „Discovery Entry Points for Agents" w CLAUDE.md — `service.yaml`
jest kontraktem operacyjnym, z którego agent czyta, jak zarządzać serwisem), więc jest kontraktem operacyjnym, z którego agent czyta, jak zarządzać serwisem), więc
@ -110,7 +110,7 @@ na próg wyłączenia) w `1784804667795`, tak samo jak istniejący trigger na
### HA ken: guard TRV kalibracji przed sezonem grzewczym (~2026-09) ### HA ken: guard TRV kalibracji przed sezonem grzewczym (~2026-09)
**Data**: 2026-07-23 **Data**: 2026-07-23
**Źródło**: `services/home-assistant/docs/audyt-automatyzacji-2026-07-23.md` sekcja 1.4 **Źródło**: `kb/audits/ha-automatyzacje-2026-07-23.md` sekcja 1.4
(pkt 2 checklisty operatora) (pkt 2 checklisty operatora)
**Problem**: kalibracje TRV sypialnia (`1764751049013`) i Tymek (`1765817937658`) liczą **Problem**: kalibracje TRV sypialnia (`1764751049013`) i Tymek (`1765817937658`) liczą
`room_temp` jako średnią z czujnika zhimi, który jest `unavailable` od 2026-07-17 → `room_temp` jako średnią z czujnika zhimi, który jest `unavailable` od 2026-07-17 →
@ -129,7 +129,7 @@ urządzenie zniknęło z sieci).
### HA ken: przycisk graceful shutdown klimy salonowej na kartę dashboardu ### HA ken: przycisk graceful shutdown klimy salonowej na kartę dashboardu
**Data**: 2026-07-23 **Data**: 2026-07-23
**Źródło**: `services/home-assistant/docs/audyt-automatyzacji-2026-07-23.md` sekcja 3.1, **Źródło**: `kb/audits/ha-automatyzacje-2026-07-23.md` sekcja 3.1,
fix-pack 1 (`task/ha-fix-pack-1`, DESIGN.md „Decyzje operatora po audycie 2026-07-23") fix-pack 1 (`task/ha-fix-pack-1`, DESIGN.md „Decyzje operatora po audycie 2026-07-23")
**Kontekst**: po fix-packu 1 „Klima salon: wyłącz…" (`1784804668795`) respektuje **Kontekst**: po fix-packu 1 „Klima salon: wyłącz…" (`1784804668795`) respektuje
`klima_salon_auto = on` dla gałęzi sunset/balkon; suszenie parownika przy ręcznym `klima_salon_auto = on` dla gałęzi sunset/balkon; suszenie parownika przy ręcznym
@ -145,7 +145,7 @@ wymagało znajomości wewnętrznej logiki automatyzacji.
### HA ken: diagnoza wspólnej awarii sprzętowej 2026-07-17 (czujniki ruchu, pilot 4button, xiaomi_miot) ### HA ken: diagnoza wspólnej awarii sprzętowej 2026-07-17 (czujniki ruchu, pilot 4button, xiaomi_miot)
**Data**: 2026-07-23 **Data**: 2026-07-23
**Źródło**: `services/home-assistant/docs/audyt-automatyzacji-2026-07-23.md` sekcje 1.2, **Źródło**: `kb/audits/ha-automatyzacje-2026-07-23.md` sekcje 1.2,
1.6, 4.5 (pkt 1, 3, 15 checklisty operatora) 1.6, 4.5 (pkt 1, 3, 15 checklisty operatora)
**Problem**: restart HA / update Supervisora 2026-07-17 15:07 zbiega się z **Problem**: restart HA / update Supervisora 2026-07-17 15:07 zbiega się z
`unavailable` na: klaster czujników ruchu/obecności (mdwejscie, mdsypialnia, mdheli — `unavailable` na: klaster czujników ruchu/obecności (mdwejscie, mdsypialnia, mdheli —
@ -166,7 +166,7 @@ automatyzacji (alerty on-leave, nocne gaszenie, `Poranek start`) — patrz audyt
### HA ken: projekt „architektura night_mode" (konsolidacja sleep/night mode) ### HA ken: projekt „architektura night_mode" (konsolidacja sleep/night mode)
**Data**: 2026-07-23 **Data**: 2026-07-23
**Źródło**: `services/home-assistant/docs/audyt-automatyzacji-2026-07-23.md` sekcje 2.2, **Źródło**: `kb/audits/ha-automatyzacje-2026-07-23.md` sekcje 2.2,
2.4, 6 (pkt 7, 9 checklisty operatora — świadomie NIE załatane w fix-packu 1, patrz 2.4, 6 (pkt 7, 9 checklisty operatora — świadomie NIE załatane w fix-packu 1, patrz
DESIGN.md „Decyzje operatora po audycie 2026-07-23") DESIGN.md „Decyzje operatora po audycie 2026-07-23")
**Problem**: cztery flagi trybu (`sleep_mode`, `night_mode`, `passive_mode`, **Problem**: cztery flagi trybu (`sleep_mode`, `night_mode`, `passive_mode`,
@ -284,7 +284,7 @@ przyciskami approve/reject per pending action.
**Data**: 2026-07-22 **Data**: 2026-07-22
**Źródło**: sesja 2026-07-22/23 (`docs/sessions/2026-07-23-control-plane-remediation-e2e.md`) **Źródło**: sesja 2026-07-22/23 (`docs/sessions/2026-07-23-control-plane-remediation-e2e.md`)
**Problem**: kontener `homeassistant5` (legacy HA "ken", patrz cutover **Problem**: kontener `homeassistant5` (legacy HA "ken", patrz cutover
`docs/backlog.md` sekcja "Cutover HA ken") zaobserwowany w stanie `Exited (0)` — exit `kb/phases/backlog.md` sekcja "Cutover HA ken") zaobserwowany w stanie `Exited (0)` — exit
code 0 = czyste zatrzymanie, więc Docker `restart: unless-stopped` świadomie go nie code 0 = czyste zatrzymanie, więc Docker `restart: unless-stopped` świadomie go nie
podnosi (to nie crash). Do zweryfikowania, czy to zamierzone wygaszenie z cutoveru czy podnosi (to nie crash). Do zweryfikowania, czy to zamierzone wygaszenie z cutoveru czy
coś zatrzymało kontener niezamierzenie. coś zatrzymało kontener niezamierzenie.

View file

@ -12,7 +12,7 @@ links:
## M1 aktywna na SOLARII — cleanup node-agenta wyłączony do czasu R1 (2026-08-04) ## M1 aktywna na SOLARII — cleanup node-agenta wyłączony do czasu R1 (2026-08-04)
**Data**: 2026-08-04 **Data**: 2026-08-04
**Źródło**: `docs/incidents/2026-07-30-ollama-solaria-vanish.md` (§7, M1). **Źródło**: `kb/incidents/2026-07-30-ollama-solaria-vanish.md` (§7, M1).
**Stan**: w `hosts/solaria/runtime/node-agent/docker-compose.override.yml` ustawiono **Stan**: w `hosts/solaria/runtime/node-agent/docker-compose.override.yml` ustawiono
`NODE_TYPE=lte_node` (było `ai_node`) na czas backfillu embed (faza mailowa KB). `NODE_TYPE=lte_node` (było `ai_node`) na czas backfillu embed (faza mailowa KB).
`lte_node` powoduje wczesny return w `run_safe_cleanup()`, więc na SOLARII nie działa `lte_node` powoduje wczesny return w `run_safe_cleanup()`, więc na SOLARII nie działa

View file

@ -9,8 +9,8 @@ links:
--- ---
## Rozjazdy repo<->rzeczywistosc (z inwentaryzacji 2026-06-30) ## Rozjazdy repo<->rzeczywistosc (z inwentaryzacji 2026-06-30)
**Zrodlo**: `docs/infra/inventory-2026-06-30.md` (23 rozjazdy, pelna tabela tam). **Zrodlo**: `kb/subsystems/fleet-inventory.md` (23 rozjazdy, pelna tabela tam).
**Weryfikacja 2026-07-02**: `docs/infra/inventory-verify-2026-07-02.md` — bilans: **Weryfikacja 2026-07-02**: `kb/subsystems/fleet-inventory-verify.md` — bilans:
20 wciaz aktualnych, 2 zmienione, 1 wyjasniony (storage SOLARIA = partycja Windows 20 wciaz aktualnych, 2 zmienione, 1 wyjasniony (storage SOLARIA = partycja Windows
dual-boot, NIE rozjazd — zdjety z listy). dual-boot, NIE rozjazd — zdjety z listy).
Ponizej te wymagajace akcji, pogrupowane wg ryzyka. Naprawa = osobny task/kilka. Ponizej te wymagajace akcji, pogrupowane wg ryzyka. Naprawa = osobny task/kilka.
@ -50,7 +50,7 @@ Ponizej te wymagajace akcji, pogrupowane wg ryzyka. Naprawa = osobny task/kilka.
- **stability-agent / node_exporter** owner_node single, biegaja wielomiejscowo -> per-host - **stability-agent / node_exporter** owner_node single, biegaja wielomiejscowo -> per-host
### Followupy z weryfikacji + rozbrajania min (2026-07-02) ### Followupy z weryfikacji + rozbrajania min (2026-07-02)
**Zrodlo**: `docs/infra/inventory-verify-2026-07-02.md` + sesja 2026-07-02. **Zrodlo**: `kb/subsystems/fleet-inventory-verify.md` + sesja 2026-07-02.
Zgloszone przy fixie owner_node (`886bc85`), swiadomie NIE ruszone — osobne decyzje. Zgloszone przy fixie owner_node (`886bc85`), swiadomie NIE ruszone — osobne decyzje.
- **forgejo** brak wpisu w `hosts/piha/services.yaml`; **mosquitto** brak - **forgejo** brak wpisu w `hosts/piha/services.yaml`; **mosquitto** brak

View file

@ -116,7 +116,7 @@ konsumentów tego pola — szeroki `except` maskował dokładnie tę klasę regr
> „Ghosty B WRÓCIŁY" w Aktywnych (`docs/sessions/2026-07-06.md`). > „Ghosty B WRÓCIŁY" w Aktywnych (`docs/sessions/2026-07-06.md`).
**Data**: 2026-06-24 (wykryte), 2026-07-02 (zamknięte) **Data**: 2026-06-24 (wykryte), 2026-07-02 (zamknięte)
**Źródło**: sesje 2026-06-24/25/26; recon `docs/infra/inventory-verify-2026-07-02.md` **Źródło**: sesje 2026-06-24/25/26; recon `kb/subsystems/fleet-inventory-verify.md`
**Było**: martwe kontenery ze starych project-name'ów **Było**: martwe kontenery ze starych project-name'ów
(`8547b46c0317_control-plane-supervisor` itp.) raportowane przez observera jako (`8547b46c0317_control-plane-supervisor` itp.) raportowane przez observera jako
`error``System Status ERROR` w panelu mimo zdrowego mózgu. `error``System Status ERROR` w panelu mimo zdrowego mózgu.
@ -130,7 +130,7 @@ Rozważenie czyszczenia obcych project-name przy deployu — już nieaktualne
### brain-watchdog: poll Prometheus — POTWIERDZONY (recon 2026-07-02) ### brain-watchdog: poll Prometheus — POTWIERDZONY (recon 2026-07-02)
**Data**: 2026-06-30 (pending), 2026-07-02 (zamknięte) **Data**: 2026-06-30 (pending), 2026-07-02 (zamknięte)
**Źródło**: recon `docs/infra/inventory-verify-2026-07-02.md` **Źródło**: recon `kb/subsystems/fleet-inventory-verify.md`
**Było**: log startowy nie wypisuje `PROMETHEUS_URL` → brak pewności, że polling **Było**: log startowy nie wypisuje `PROMETHEUS_URL` → brak pewności, że polling
aktywny; diagnoza opierała się na `.env` i braku błędów. aktywny; diagnoza opierała się na `.env` i braku błędów.
**Zamknięte**: recon potwierdził — obraz zbudowany po `62d6fc0`, `PROMETHEUS_URL` **Zamknięte**: recon potwierdził — obraz zbudowany po `62d6fc0`, `PROMETHEUS_URL`
@ -144,7 +144,7 @@ bez czekania na realną awarię.
### Miny #1/#2/#3 z weryfikacji inwentaryzacji — ROZBROJONE (2026-07-02) ### Miny #1/#2/#3 z weryfikacji inwentaryzacji — ROZBROJONE (2026-07-02)
**Źródło**: `docs/infra/inventory-verify-2026-07-02.md`, sesja **Źródło**: `kb/subsystems/fleet-inventory-verify.md`, sesja
`docs/sessions/2026-07-02.md` (tam szczegóły i lekcje). `docs/sessions/2026-07-02.md` (tam szczegóły i lekcje).
- **#1 PIHA checkout**: gałąź wciąż `task/kb-gmail-import` po resecie z 2026-06-30 - **#1 PIHA checkout**: gałąź wciąż `task/kb-gmail-import` po resecie z 2026-06-30
(reset --hard przesuwa gałąź, nie przełącza) → `checkout master && pull`, (reset --hard przesuwa gałąź, nie przełącza) → `checkout master && pull`,

View file

@ -20,5 +20,5 @@ exited at line 18 with `Error: Repository not found`. Behind that failure sat
three more: no `git`, no `docker` CLI in the image, and — had it ever got that three more: no `git`, no `docker` CLI in the image, and — had it ever got that
far — it would have deployed the **executor host's** entire service set, not the far — it would have deployed the **executor host's** entire service set, not the
action's target node/service. Every `healthcheck_failed → redeploy` dead-ended action's target node/service. Every `healthcheck_failed → redeploy` dead-ended
(recon `docs/architecture/RECON-multiagent-2026-07-27.md`, D14/D15). (recon `kb/subsystems/recon-multiagent.md`, D14/D15).

View file

@ -13,7 +13,7 @@ links:
Status: **phase 1 (partial)**. `scripts/ha/deploy.sh` implements the write Status: **phase 1 (partial)**. `scripts/ha/deploy.sh` implements the write
path for the `api` adapter's automations/scripts/scenes scope (see "Deploy path for the `api` adapter's automations/scripts/scenes scope (see "Deploy
path" and "Sync model" below); dashboards/helpers and the `docker-exec` path" and "Sync model" below); dashboards/helpers and the `docker-exec`
adapter have no write path yet. See `docs/backlog.md` for the tracking adapter have no write path yet. See `kb/phases/backlog.md` for the tracking
entry. entry.
## Phasing ## Phasing
@ -59,7 +59,7 @@ behind a common interface (`import.sh`/eventual `deploy.sh <instance>`):
|---|---|---| |---|---|---|
| `ken` (RPi4, HAOS, LAN `192.168.31.7:8123`) | **api** | Canonical home instance since the 2026-07-22 cutover (see Incident log). HAOS has no SSH access, so there is no `docker exec`/filesystem path — only the HA REST/websocket API is reachable. Full `/config` import is deferred until an alternative access path exists; for now the api adapter's import scope is limited to what the API exposes: automations, scripts, scenes, dashboards. | | `ken` (RPi4, HAOS, LAN `192.168.31.7:8123`) | **api** | Canonical home instance since the 2026-07-22 cutover (see Incident log). HAOS has no SSH access, so there is no `docker exec`/filesystem path — only the HA REST/websocket API is reachable. Full `/config` import is deferred until an alternative access path exists; for now the api adapter's import scope is limited to what the API exposes: automations, scripts, scenes, dashboards. |
| `ken-legacy` (piha, container `homeassistant5`) | **docker-exec over SSH** (archive-only) | Pre-migration container instance, superseded by `ken` at 31.7 (see Incident log) — same container filesystem access as the old `ken` entry (`ssh oskar@piha "docker exec homeassistant5 ..."`). Import only, for historical reference; never a deploy target. | | `ken-legacy` (piha, container `homeassistant5`) | **docker-exec over SSH** (archive-only) | Pre-migration container instance, superseded by `ken` at 31.7 (see Incident log) — same container filesystem access as the old `ken` entry (`ssh oskar@piha "docker exec homeassistant5 ..."`). Import only, for historical reference; never a deploy target. |
| `chelsty-ha` | **api** | Reachable over Tailscale at `100.70.180.90:8123` (confirmed working path — `services/ha-diag-agent/DEPLOY.md` already curls this for health checks). Config-as-code deploy will reuse the same reachability, calling the HA REST/websocket API rather than shelling into the container. | | `chelsty-ha` | **api** | Reachable over Tailscale at `100.70.180.90:8123` (confirmed working path — `kb/runbooks/ha-diag-agent-deploy.md` already curls this for health checks). Config-as-code deploy will reuse the same reachability, calling the HA REST/websocket API rather than shelling into the container. |
**Open**: a `file` adapter (direct bind-mount / SSH `rsync` to the config **Open**: a `file` adapter (direct bind-mount / SSH `rsync` to the config
directory, bypassing `docker exec`) is worth revisiting once SSH access to directory, bypassing `docker exec`) is worth revisiting once SSH access to
@ -124,7 +124,7 @@ copied into the repo.
- A dedicated `deploy_agent` HA user account (admin rights, **local-only** - A dedicated `deploy_agent` HA user account (admin rights, **local-only**
— never exposed through the public API/ingress) is created per instance, — never exposed through the public API/ingress) is created per instance,
mirroring the existing `diag_agent` account pattern documented in mirroring the existing `diag_agent` account pattern documented in
`services/ha-diag-agent/DEPLOY.md`. Reusing `diag_agent` is explicitly `kb/runbooks/ha-diag-agent-deploy.md`. Reusing `diag_agent` is explicitly
rejected — deploy tooling and the diagnostic agent must be revocable rejected — deploy tooling and the diagnostic agent must be revocable
independently. independently.
- Long-lived access tokens for `deploy_agent` live at - Long-lived access tokens for `deploy_agent` live at
@ -150,7 +150,7 @@ Zobacz `docs/audyt-automatyzacji-2026-07-23.md` (sekcja "Do decyzji operatora",
17 punktów) — poniżej wyłącznie decyzje, które doprowadziły do zmian w 17 punktów) — poniżej wyłącznie decyzje, które doprowadziły do zmian w
fix-pack 1 (`task/ha-fix-pack-1`) albo świadomie do braku zmian. Reszta fix-pack 1 (`task/ha-fix-pack-1`) albo świadomie do braku zmian. Reszta
checklisty (baterie/re-pairing czujników, kalibracje TRV, xiaomi_miot, checklisty (baterie/re-pairing czujników, kalibracje TRV, xiaomi_miot,
konsolidacja aliasów, higiena 4.x) zostaje otwarta w `docs/backlog.md`. konsolidacja aliasów, higiena 4.x) zostaje otwarta w `kb/phases/backlog.md`.
- **Pkt 6 (klima salon: sunset ubija też ręczne chłodzenie?)** — decyzja: - **Pkt 6 (klima salon: sunset ubija też ręczne chłodzenie?)** — decyzja:
NIE. „Klima salon: wyłącz…" (`1784804668795`) ma teraz respektować NIE. „Klima salon: wyłącz…" (`1784804668795`) ma teraz respektować
@ -166,7 +166,7 @@ konsolidacja aliasów, higiena 4.x) zostaje otwarta w `docs/backlog.md`.
- **Pkt 7 (enforcer sleep mode gasi światła cyklicznie całą noc) i pkt 9 - **Pkt 7 (enforcer sleep mode gasi światła cyklicznie całą noc) i pkt 9
(konsolidacja czterech nocnych wyłączników)** — bez zmian w tym fix-packu. (konsolidacja czterech nocnych wyłączników)** — bez zmian w tym fix-packu.
Oba wchłania przyszły projekt „architektura night_mode" (patrz Oba wchłania przyszły projekt „architektura night_mode" (patrz
`docs/backlog.md`) — punktowa łatka tu tylko dodałaby kolejny wariant do `kb/phases/backlog.md`) — punktowa łatka tu tylko dodałaby kolejny wariant do
już przegęszczonego zestawu nakładających się automatyzacji (audyt 2.2). już przegęszczonego zestawu nakładających się automatyzacji (audyt 2.2).
- **Pkt 11 (OwnTracks: przywrócić czy skasować) i pkt 12 (Leave auto on: - **Pkt 11 (OwnTracks: przywrócić czy skasować) i pkt 12 (Leave auto on:
batch 02 — włączyć z powrotem?)** — świadomie bez zmian; obie wymagają batch 02 — włączyć z powrotem?)** — świadomie bez zmian; obie wymagają

View file

@ -63,7 +63,7 @@ zdecydować, czy podbić concurrency, czy zostawić zapas na ollama/AI.
rsync/borg → SOLARIA (2 TB, ta sama LAN). Retencja: 7 dziennych + rsync/borg → SOLARIA (2 TB, ta sama LAN). Retencja: 7 dziennych +
4 tygodniowe + 6 miesięcznych. Offsite (np. restic → chmura) zostaje jako 4 tygodniowe + 6 miesięcznych. Offsite (np. restic → chmura) zostaje jako
future-note, poza zakresem tego etapu. Cron/skrypt deployowy powstaje przy future-note, poza zakresem tego etapu. Cron/skrypt deployowy powstaje przy
deployu modułu 2, nie teraz. Szczegóły: `services/paperless/README.md`. deployu modułu 2, nie teraz. Szczegóły: `kb/services/paperless.md`.
- **4. Redis brokera: `requirepass`.** Broker (6380) dostaje hasło — - **4. Redis brokera: `requirepass`.** Broker (6380) dostaje hasło —
`PAPERLESS_REDIS_PASSWORD` w `.env` po obu stronach (paperless@PIHA, `PAPERLESS_REDIS_PASSWORD` w `.env` po obu stronach (paperless@PIHA,
@ -76,7 +76,7 @@ zdecydować, czy podbić concurrency, czy zostawić zapas na ollama/AI.
+ SOLARIA po NFS) świadomie zaakceptowane — indeks jest odtwarzalny + SOLARIA po NFS) świadomie zaakceptowane — indeks jest odtwarzalny
(`document_index reindex`), oryginałom nic nie grozi. Bez zmian w (`document_index reindex`), oryginałom nic nie grozi. Bez zmian w
configu; fallback-worker na PIHA zostaje. Szczegóły: configu; fallback-worker na PIHA zostaje. Szczegóły:
`services/paperless-worker/README.md`. `kb/services/paperless-worker.md`.
- **6. Domeny: `kapala.org` (mesh, prywatne).** `paper.kapala.org` - **6. Domeny: `kapala.org` (mesh, prywatne).** `paper.kapala.org`
(Paperless), `cloud.kapala.org` (Nextcloud) — potwierdzone, `*.okit.pl` (Paperless), `cloud.kapala.org` (Nextcloud) — potwierdzone, `*.okit.pl`
@ -99,7 +99,7 @@ zdecydować, czy podbić concurrency, czy zostawić zapas na ollama/AI.
maintainerów paperless-ngx (nieoficjalnie wspierany): ten sam obraz, maintainerów paperless-ngx (nieoficjalnie wspierany): ten sam obraz,
`command: celery --app paperless worker`, wspólny Redis+Postgres+storage, `command: celery --app paperless worker`, wspólny Redis+Postgres+storage,
identyczne ścieżki kontenerowe i numeryczny UID po obu stronach. Pełny identyczne ścieżki kontenerowe i numeryczny UID po obu stronach. Pełny
wynik badania + ryzyka: `services/paperless-worker/README.md`. wynik badania + ryzyka: `kb/services/paperless-worker.md`.
- Storage dokumentów na PIHA; NFS export → SOLARIA po LAN - Storage dokumentów na PIHA; NFS export → SOLARIA po LAN
(192.168.31.5 → 192.168.31.70), nie Tailscale. (192.168.31.5 → 192.168.31.70), nie Tailscale.
- AOF w Redis brokera (kolejka przeżywa restart — zero utraty zadań). - AOF w Redis brokera (kolejka przeżywa restart — zero utraty zadań).

View file

@ -29,5 +29,5 @@ widzieć **ten sam Redis, tego samego Postgresa i te same pliki**. Stąd:
restart brokera nie gubi kolejki). restart brokera nie gubi kolejki).
Szczegóły NFS (export na PIHA, mount na SOLARIA, ryzyko indeksu Whoosh) — Szczegóły NFS (export na PIHA, mount na SOLARIA, ryzyko indeksu Whoosh) —
`services/paperless-worker/README.md`. `kb/services/paperless-worker.md`.

View file

@ -5,7 +5,7 @@ visibility: private
status: deprecated status: deprecated
updated: 2026-06-24 updated: 2026-06-24
links: [] links: []
superseded_by: "kb/phases/backlog.md (docs/backlog.md przejal ewidencje dlugu)" superseded_by: "kb/phases/backlog.md (kb/phases/backlog.md przejal ewidencje dlugu)"
--- ---
# Tech Debt # Tech Debt

View file

@ -30,7 +30,7 @@ zdeployowany i brał zadania z kolejki, ale miał dwa bugi w compose:
mount na `/tmp/paperless` po obu stronach. mount na `/tmp/paperless` po obu stronach.
Oba fixy + uzasadnienie: `services/paperless/docker-compose.yml`, Oba fixy + uzasadnienie: `services/paperless/docker-compose.yml`,
`services/paperless-worker/docker-compose.yml`, `services/paperless-worker/README.md`. `services/paperless-worker/docker-compose.yml`, `kb/services/paperless-worker.md`.
Zweryfikowane end-to-end na żywo (branch `task/paperless-worker-fix`, jeszcze Zweryfikowane end-to-end na żywo (branch `task/paperless-worker-fix`, jeszcze
niezmergowany do master w momencie pisania tego wpisu): 3 dokumenty testowe niezmergowany do master w momencie pisania tego wpisu): 3 dokumenty testowe
wrzucone do `consume/` na PIHA, jeden odebrany i dokończony przez worker@SOLARIA wrzucone do `consume/` na PIHA, jeden odebrany i dokończony przez worker@SOLARIA

View file

@ -10,7 +10,7 @@ links:
## Ollama SOLARIA: brak sterownika NVIDII — ZAMKNIĘTE (2026-07-16) ## Ollama SOLARIA: brak sterownika NVIDII — ZAMKNIĘTE (2026-07-16)
**Kontekst.** Cutover 2026-07-15 (`docs/infra/ollama-solaria-cutover-2026-07-15.md`) **Kontekst.** Cutover 2026-07-15 (`kb/runbooks/ollama-solaria-cutover.md`)
odkrył, że SOLARIA nie miała zainstalowanego żadnego sterownika NVIDII — odkrył, że SOLARIA nie miała zainstalowanego żadnego sterownika NVIDII —
`nvidia-smi` nie istniał na hoście. `hosts/solaria/services.yaml` opisywał `nvidia-smi` nie istniał na hoście. `hosts/solaria/services.yaml` opisywał
ollama jako "GPU-backed" od dawna, ale to było aspiracyjne — Ollama zawsze ollama jako "GPU-backed" od dawna, ale to było aspiracyjne — Ollama zawsze
@ -24,7 +24,7 @@ jako blokujący fazę mailową embeddingów (moduł 5).
hoście. `nvidia-container-toolkit` był już obecny (doinstalowany jako hoście. `nvidia-container-toolkit` był już obecny (doinstalowany jako
prerequisite przy cutoverze 07-15). GPU reservation przywrócona w compose. prerequisite przy cutoverze 07-15). GPU reservation przywrócona w compose.
Pomiar throughput GPU vs CPU baseline (0.79s/chunk) — patrz Pomiar throughput GPU vs CPU baseline (0.79s/chunk) — patrz
`jobs/documents-ingest/README.md`, sekcja timing. `kb/phases/kb-m5-documents-ingest-fazy.md`, sekcja timing.
**Status:** ZAMKNIĘTE. **Status:** ZAMKNIĘTE.
@ -35,6 +35,6 @@ Pomiar throughput GPU vs CPU baseline (0.79s/chunk) — patrz
- **`UNIQUE(envelope_id, chunk_index)` bez `model`** w `document_chunk` - **`UNIQUE(envelope_id, chunk_index)` bez `model`** w `document_chunk`
(`services/kb-postgres/init/002_chunks.sql`) — re-embedding innym modelem (`services/kb-postgres/init/002_chunks.sql`) — re-embedding innym modelem
cicho no-opuje się przez istniejący constraint. Schema change do zrobienia cicho no-opuje się przez istniejący constraint. Schema change do zrobienia
przy fazie 3 (patrz `jobs/documents-ingest/README.md`, sekcja "Idempotency" przy fazie 3 (patrz `kb/phases/kb-m5-documents-ingest-fazy.md`, sekcja "Idempotency"
kroku 6 embed). kroku 6 embed).

View file

@ -37,7 +37,7 @@ followed the move.
**Decision**: 192.168.31.7 (HAOS/RPi4) is canonical `ken`. The piha **Decision**: 192.168.31.7 (HAOS/RPi4) is canonical `ken`. The piha
container is renamed `ken-legacy` in `instances.yaml`, `status: archived`. container is renamed `ken-legacy` in `instances.yaml`, `status: archived`.
Plan: archival import for historical reference → `docker stop` (not `rm`) Plan: archival import for historical reference → `docker stop` (not `rm`)
→ one week of observation → decide on `docker rm`. See `docs/backlog.md` → one week of observation → decide on `docker rm`. See `kb/phases/backlog.md`
for the ha-diag-agent re-pointing and wind-down follow-ups this incident for the ha-diag-agent re-pointing and wind-down follow-ups this incident
generated. generated.

View file

@ -13,7 +13,7 @@ links:
**Data**: 2026-07-22 **Data**: 2026-07-22
**Źródło**: recon — dwie instancje HA równolegle sterowały domem (kontener **Źródło**: recon — dwie instancje HA równolegle sterowały domem (kontener
`homeassistant5` na piha + RPi4 HAOS 192.168.31.7), patrz `homeassistant5` na piha + RPi4 HAOS 192.168.31.7), patrz
`services/home-assistant/DESIGN.md` sekcja "Incident log". `instances.yaml` `kb/decisions/ha-configs-as-code.md` sekcja "Incident log". `instances.yaml`
naprawiony w tej samej sesji: `ken` = 192.168.31.7 (api), `ken-legacy` = naprawiony w tej samej sesji: `ken` = 192.168.31.7 (api), `ken-legacy` =
dawny kontener piha (docker-exec, archived). dawny kontener piha (docker-exec, archived).

View file

@ -17,7 +17,7 @@ Szkielet struktury dla `services/home-assistant/` — configs-as-code dla
instancji HA (`ken` na PIHA, `chelsty-ha`). Na razie tylko struktura + instancji HA (`ken` na PIHA, `chelsty-ha`). Na razie tylko struktura +
read-only import (`scripts/ha/import.sh`), bez deployu. Fazowanie, wybór read-only import (`scripts/ha/import.sh`), bez deployu. Fazowanie, wybór
adaptera per instancja, model sync i otwarte pytania — adaptera per instancja, model sync i otwarte pytania —
`services/home-assistant/DESIGN.md`. `kb/decisions/ha-configs-as-code.md`.
--- ---

View file

@ -15,7 +15,7 @@ links: []
## STATUS: prerekwizyt RAM SPELNIONY (2026-07-02) ## STATUS: prerekwizyt RAM SPELNIONY (2026-07-02)
Faza 1 (audyt read-only) + faza 2 (egzekucja po review Oskara) wykonane — Faza 1 (audyt read-only) + faza 2 (egzekucja po review Oskara) wykonane —
szczegoly: `docs/infra/piha-slim-audit-2026-07-02.md` (sekcja "Korekta po review szczegoly: `kb/audits/piha-slim-2026-07-02.md` (sekcja "Korekta po review
+ egzekucja"). + egzekucja").
- **Kryterium >= 1.5Gi available: SPELNIONE.** Przed egzekucja: 2.8Gi available - **Kryterium >= 1.5Gi available: SPELNIONE.** Przed egzekucja: 2.8Gi available
@ -37,7 +37,7 @@ Zwolnic RAM na PIHA (dzis: 3.1Gi available, swap 2G uzyty) tak, by lekki Paperle
serwis wszedl z zapasem, nie na styku swap. serwis wszedl z zapasem, nie na styku swap.
## Wymogi ## Wymogi
- Audyt 33 shadow-kontenerow (lista w `docs/infra/inventory-2026-06-30.md`). - Audyt 33 shadow-kontenerow (lista w `kb/subsystems/fleet-inventory.md`).
- Zidentyfikowac kandydatow do usuniecia/przeniesienia/wylaczenia: - Zidentyfikowac kandydatow do usuniecia/przeniesienia/wylaczenia:
- **elasticsearch 1Gi** — kto tego uzywa? (wikijs? diskover?) — jesli martwy, ubic - **elasticsearch 1Gi** — kto tego uzywa? (wikijs? diskover?) — jesli martwy, ubic
- **diskover** — jednorazowy indekser? czy chodzi ciagle bez potrzeby? - **diskover** — jednorazowy indekser? czy chodzi ciagle bez potrzeby?

View file

@ -13,7 +13,7 @@ links:
## Phase 2 — `documents-ingest-paperless` (Paperless -> envelope adapter) ## Phase 2 — `documents-ingest-paperless` (Paperless -> envelope adapter)
Module 5, phase 2 (`docs/kb/modules/05-faza2-plan.md`, §4.2-4.3, §6 step 5). Module 5, phase 2 (`kb/phases/kb-m5-faza2.md`, §4.2-4.3, §6 step 5).
Reads documents from the **Paperless REST API** (read-only — GET only, never Reads documents from the **Paperless REST API** (read-only — GET only, never
writes to Paperless) and inserts them as `source='paperless'` rows into the writes to Paperless) and inserts them as `source='paperless'` rows into the
`envelope` table on kb-postgres, reusing `kb_mail.envelope.Envelope` / `envelope` table on kb-postgres, reusing `kb_mail.envelope.Envelope` /
@ -133,7 +133,7 @@ this commit.
## Phase 2 step 6 — `documents-ingest-embed` (chunk + embed) ## Phase 2 step 6 — `documents-ingest-embed` (chunk + embed)
Module 5, phase 2, plan step 6 (`docs/kb/modules/05-faza2-plan.md`, §6 step 6, Module 5, phase 2, plan step 6 (`kb/phases/kb-m5-faza2.md`, §6 step 6,
§2 decision 3). Reads `entities[type=content].text` off every `source='paperless'` §2 decision 3). Reads `entities[type=content].text` off every `source='paperless'`
envelope, chunks it, calls Ollama (`POST /api/embeddings`, model `bge-m3`) for envelope, chunks it, calls Ollama (`POST /api/embeddings`, model `bge-m3`) for
each chunk, and inserts the result into `document_chunk` each chunk, and inserts the result into `document_chunk`
@ -311,7 +311,7 @@ kb-postgres@PIHA:
## Phase 3 step 4 — retrieval cascade (`documents_ingest.retrieval`) + quality gate ## Phase 3 step 4 — retrieval cascade (`documents_ingest.retrieval`) + quality gate
Module 5, phase 3, plan step 4 (`docs/kb/modules/05-faza3-plan.md`, §6). Two retrieval Module 5, phase 3, plan step 4 (`kb/phases/kb-m5-faza3.md`, §6). Two retrieval
paths, both `query_text -> chunk hits (dist, source)` — the intended clean API surface for paths, both `query_text -> chunk hits (dist, source)` — the intended clean API surface for
phase 4's kb-query, not just this eval: phase 4's kb-query, not just this eval:
@ -328,7 +328,7 @@ phase 4's kb-query, not just this eval:
### Quality gate ### Quality gate
`eval/queries.yaml` — 7 queries transcribed 1:1 from the phase-2 pilot baseline `eval/queries.yaml` — 7 queries transcribed 1:1 from the phase-2 pilot baseline
(`docs/kb/eval/retrieval-pilot-2026-07-16.md`, left untouched — this is its versioned working (`kb/phases/kb-m5-eval-retrieval-pilot.md`, left untouched — this is its versioned working
copy) with expected envelope / kind (`hit`, `grey_zone`, `negative_control`, copy) with expected envelope / kind (`hit`, `grey_zone`, `negative_control`,
`negative_control_borderline`) per query. `negative_control_borderline`) per query.
@ -373,7 +373,7 @@ short-circuit (stage 2 never queried), and both query entry points embedding exa
## Phase 3 step 5 — cyclic ingest (`documents-ingest-cyclic`) + systemd timer ## Phase 3 step 5 — cyclic ingest (`documents-ingest-cyclic`) + systemd timer
Module 5, phase 3, plan step 5 (`docs/kb/modules/05-faza3-plan.md`, §7). Orchestrates one Module 5, phase 3, plan step 5 (`kb/phases/kb-m5-faza3.md`, §7). Orchestrates one
run of the recurring ingest pipeline: `paperless_adapter.run()` (new `source='paperless'` run of the recurring ingest pipeline: `paperless_adapter.run()` (new `source='paperless'`
envelopes) → `chunk_embed.run()` (new `document_chunk` rows) → envelopes) → `chunk_embed.run()` (new `document_chunk` rows) →
`summarize.run_summarize(backend='anthropic')` (new `document_summary` rows, `summarize.run_summarize(backend='anthropic')` (new `document_summary` rows,

View file

@ -545,7 +545,7 @@ zeby dalo sie uruchomic partiami i zweryfikowac progres bez czekania na cale 225
rzedu dziesiatek-set chunkow/s. Caly pilot (23k chunkow) → **rzedu minut**, nie wymaga rzedu dziesiatek-set chunkow/s. Caly pilot (23k chunkow) → **rzedu minut**, nie wymaga
specjalnego batchowania/partii. specjalnego batchowania/partii.
- **Skala docelowa (70k zalacznikow z maili)**: modul 5 faza-1 to swiadomie **probka, nie - **Skala docelowa (70k zalacznikow z maili)**: modul 5 faza-1 to swiadomie **probka, nie
bulk** (`jobs/documents-ingest/README.md` — decyzja architektoniczna). Realny wolumen bulk** (`kb/phases/kb-m5-documents-ingest-fazy.md` — decyzja architektoniczna). Realny wolumen
ktory trafi do embeddingu zalezy od (a) throughput OCR-workera na SOLARII (modul 3) — ktory trafi do embeddingu zalezy od (a) throughput OCR-workera na SOLARII (modul 3) —
**to jest waskie gardlo skalowania, nie embedding** — oraz (b) filtra selektywnosci **to jest waskie gardlo skalowania, nie embedding** — oraz (b) filtra selektywnosci
(decyzja #6). Sam embedding bge-m3 nie bedzie bottleneckiem nawet przy tysiacach (decyzja #6). Sam embedding bge-m3 nie bedzie bottleneckiem nawet przy tysiacach

View file

@ -505,7 +505,7 @@ aktywnych chunków, N większe niż liczba kopert, no-summaries short-circuit)
pakietu przechodzi. pakietu przechodzi.
**Eval-set utrwalony**: `jobs/documents-ingest/eval/queries.yaml` (7 zapytań z pilota **Eval-set utrwalony**: `jobs/documents-ingest/eval/queries.yaml` (7 zapytań z pilota
07-16, 1:1 z `docs/kb/eval/retrieval-pilot-2026-07-16.md`, ten plik pozostał nietknięty — 07-16, 1:1 z `kb/phases/kb-m5-eval-retrieval-pilot.md`, ten plik pozostał nietknięty —
`queries.yaml` to jego wersjonowana kopia robocza). Skrypt bramki (read-only, integracyjny, `queries.yaml` to jego wersjonowana kopia robocza). Skrypt bramki (read-only, integracyjny,
**nie wchodzi do pytest**): `jobs/documents-ingest/eval/retrieval_eval.py`. **nie wchodzi do pytest**): `jobs/documents-ingest/eval/retrieval_eval.py`.
@ -700,7 +700,7 @@ streszczeń). Kandydaci na pierwsze strony (encje z pilota): PZU/WARTA (polisy),
## 9. Poza zakresem fazy 3 ## 9. Poza zakresem fazy 3
Granice planu — wszystko poniżej jest świadomie odłożone, z istniejącym miejscem w Granice planu — wszystko poniżej jest świadomie odłożone, z istniejącym miejscem w
roadmapie (`docs/kb/kb-00-overview.md` „Stan etapów/Backlog", sesja roadmapie (`kb/subsystems/kb-overview.md` „Stan etapów/Backlog", sesja
`docs/sessions/2026-07-16.md`, backlog operatora): `docs/sessions/2026-07-16.md`, backlog operatora):
| Temat | Gdzie zakotwiczone | Kiedy | | Temat | Gdzie zakotwiczone | Kiedy |

View file

@ -71,10 +71,10 @@ zegarem, master trzyma to samo wewnątrz `EmbedRouter` (też injektowalny zegar)
| `services/kb-query/{README,env.example,service.yaml,docker-compose.yml}` | ~±58 | duplikat | **porzuć** | inny (porzucony) schemat env `OLLAMA_PIHA_URL`; master bogatszy (testy A/B/C, rename `OLLAMA_URL`→`EMBED_PRIMARY_URL`) | | `services/kb-query/{README,env.example,service.yaml,docker-compose.yml}` | ~±58 | duplikat | **porzuć** | inny (porzucony) schemat env `OLLAMA_PIHA_URL`; master bogatszy (testy A/B/C, rename `OLLAMA_URL`→`EMBED_PRIMARY_URL`) |
| `packages/kb-retrieval/src/kb_retrieval/embed.py` (`timeout_s` w `embed_chunk`) | +16 | duplikat funkcji | **porzuć** | master osiąga twardy timeout przez `asyncio.wait_for` bez zmiany współdzielonego pakietu — mniejsza powierzchnia zmian, ten sam efekt | | `packages/kb-retrieval/src/kb_retrieval/embed.py` (`timeout_s` w `embed_chunk`) | +16 | duplikat funkcji | **porzuć** | master osiąga twardy timeout przez `asyncio.wait_for` bez zmiany współdzielonego pakietu — mniejsza powierzchnia zmian, ten sam efekt |
| `jobs/documents-ingest/eval/retrieval_eval.py` (`--transport {direct,http}` + `--base-url`) | +109 | **unikalna wartość** | **cherry-pick** | plan §2 decyzja 6 / §9 (bramka HTTP-equivalence) — **na masterze w ogóle nie istnieje**; e7625cd nie tknął tego pliku, patch aplikuje się czysto; kod woła tylko `GET /search` i czyta `envelope_id`/`dist`/`source` — w pełni zgodny z odpowiedzią mastera | | `jobs/documents-ingest/eval/retrieval_eval.py` (`--transport {direct,http}` + `--base-url`) | +109 | **unikalna wartość** | **cherry-pick** | plan §2 decyzja 6 / §9 (bramka HTTP-equivalence) — **na masterze w ogóle nie istnieje**; e7625cd nie tknął tego pliku, patch aplikuje się czysto; kod woła tylko `GET /search` i czyta `envelope_id`/`dist`/`source` — w pełni zgodny z odpowiedzią mastera |
| `jobs/documents-ingest/README.md` | +6 | **unikalna wartość** | **cherry-pick** | dokumentacja powyższego, idzie w parze | | `kb/phases/kb-m5-documents-ingest-fazy.md` | +6 | **unikalna wartość** | **cherry-pick** | dokumentacja powyższego, idzie w parze |
| `docs/sessions/2026-07-27-kb-f4-fallback.md` | +189 | **unikalna wartość** | **adaptuj** | jedyny zapis: (1) znalezisko osieroconego natywnego `ollama.service` na PIHA + jego wyłączenie 2026-07-27 i backlog odinstalowania, (2) kalibracja live ollama-piha (GO: peak ~983 MiB, ~4.25.3 s/embed), (3) metodologia i wyniki bramki §9 (HTTP-equivalence 0 rozbieżności; sol-down Δ~3e-4), (4) rsync-deploy → dirty working tree na PIHA. Wciągnąć z dopiskiem redakcyjnym, że zmergowana implementacja to **inny kod** (e7625cd) i wyniki bramki wymagają powtórki | | `docs/sessions/2026-07-27-kb-f4-fallback.md` | +189 | **unikalna wartość** | **adaptuj** | jedyny zapis: (1) znalezisko osieroconego natywnego `ollama.service` na PIHA + jego wyłączenie 2026-07-27 i backlog odinstalowania, (2) kalibracja live ollama-piha (GO: peak ~983 MiB, ~4.25.3 s/embed), (3) metodologia i wyniki bramki §9 (HTTP-equivalence 0 rozbieżności; sol-down Δ~3e-4), (4) rsync-deploy → dirty working tree na PIHA. Wciągnąć z dopiskiem redakcyjnym, że zmergowana implementacja to **inny kod** (e7625cd) i wyniki bramki wymagają powtórki |
| `services/ollama-piha/*` (5 plików) | +155 | duplikat | **porzuć** | wersja mastera lepsza: named volume `ollama_piha_models` (uzasadnienie uid-pattern PIHA), healthcheck sprawdza obecność `bge-m3`, bind tylko 127.0.0.1+LAN | | `services/ollama-piha/*` (5 plików) | +155 | duplikat | **porzuć** | wersja mastera lepsza: named volume `ollama_piha_models` (uzasadnienie uid-pattern PIHA), healthcheck sprawdza obecność `bge-m3`, bind tylko 127.0.0.1+LAN |
| `hosts/piha/runtime/ollama-piha/docker-compose.override.yml` | +13 | duplikat + **1 unikalny fakt** | **adaptuj (mikro)** | ten sam `mem_limit: 2560m`; ale komentarz brancha zawiera potwierdzony pomiar (peak ~983 MiB), a master wciąż mówi „Confirm/trim after live calibration" — dopisać wynik kalibracji do komentarza override'u i/lub sekcji „Calibration" w `services/ollama-piha/README.md` | | `hosts/piha/runtime/ollama-piha/docker-compose.override.yml` | +13 | duplikat + **1 unikalny fakt** | **adaptuj (mikro)** | ten sam `mem_limit: 2560m`; ale komentarz brancha zawiera potwierdzony pomiar (peak ~983 MiB), a master wciąż mówi „Confirm/trim after live calibration" — dopisać wynik kalibracji do komentarza override'u i/lub sekcji „Calibration" w `kb/services/ollama-piha.md` |
| `hosts/piha/services.yaml` | ±26 | duplikat | **porzuć** | master ma własny wpis `ollama-piha` + soft-dependency kb-query; drobna różnica (`offline_required: true` na branchu vs `false` na masterze) — master źródłem prawdy | | `hosts/piha/services.yaml` | ±26 | duplikat | **porzuć** | master ma własny wpis `ollama-piha` + soft-dependency kb-query; drobna różnica (`offline_required: true` na branchu vs `false` na masterze) — master źródłem prawdy |
--- ---
@ -107,7 +107,7 @@ skonfigurowanego → `EmbedBackendError`, `fallback_status` (up/unconfigured), s
## 4. Rekomendacja zbiorcza (lista do zatwierdzenia) ## 4. Rekomendacja zbiorcza (lista do zatwierdzenia)
1. **S1 — cherry-pick**: `retrieval_eval.py --transport http --base-url` + akapit w 1. **S1 — cherry-pick**: `retrieval_eval.py --transport http --base-url` + akapit w
`jobs/documents-ingest/README.md` (plan §2 D6/§9; aplikuje się czysto, zero zależności `kb/phases/kb-m5-documents-ingest-fazy.md` (plan §2 D6/§9; aplikuje się czysto, zero zależności
od porzuconego kodu brancha). od porzuconego kodu brancha).
2. **S2 — adaptuj**: `docs/sessions/2026-07-27-kb-f4-fallback.md``docs/sessions/` 2. **S2 — adaptuj**: `docs/sessions/2026-07-27-kb-f4-fallback.md``docs/sessions/`
z dopiskiem redakcyjnym na górze (implementacja z tej sesji porzucona na rzecz z dopiskiem redakcyjnym na górze (implementacja z tej sesji porzucona na rzecz
@ -116,7 +116,7 @@ skonfigurowanego → `EmbedBackendError`, `fallback_status` (up/unconfigured), s
3. **S3 — adaptuj**: luki testowe T1 + T2 (T3 opcjonalnie) do `test_embed_router.py`. 3. **S3 — adaptuj**: luki testowe T1 + T2 (T3 opcjonalnie) do `test_embed_router.py`.
4. **S4 — adaptuj (mikro)**: wynik kalibracji 2026-07-27 (peak ~983 MiB, ~4.25.3 s, 4. **S4 — adaptuj (mikro)**: wynik kalibracji 2026-07-27 (peak ~983 MiB, ~4.25.3 s,
werdykt GO) do komentarza `hosts/piha/runtime/ollama-piha/docker-compose.override.yml` werdykt GO) do komentarza `hosts/piha/runtime/ollama-piha/docker-compose.override.yml`
i sekcji Calibration w `services/ollama-piha/README.md` — pomiar dotyczył kontenera i sekcji Calibration w `kb/services/ollama-piha.md` — pomiar dotyczył kontenera
ollama-piha (ta sama konfiguracja: obraz, `OLLAMA_KEEP_ALIVE=0`, `mem_limit 2560m`), ollama-piha (ta sama konfiguracja: obraz, `OLLAMA_KEEP_ALIVE=0`, `mem_limit 2560m`),
więc **przenosi się** na wersję mastera; różni się tylko storage (bind vs named więc **przenosi się** na wersję mastera; różni się tylko storage (bind vs named
volume), co nie wpływa na RAM/latencję. volume), co nie wpływa na RAM/latencję.
@ -130,7 +130,7 @@ skonfigurowanego → `EmbedBackendError`, `fallback_status` (up/unconfigured), s
(3d4ee38) i worktree `~/homelab-codex-ws-kb-f4-fallback` po zakończeniu salvage. (3d4ee38) i worktree `~/homelab-codex-ws-kb-f4-fallback` po zakończeniu salvage.
- **(b) Powtórka testu sol-down na żywym masterze**: kalibracja i bramka z 2026-07-27 - **(b) Powtórka testu sol-down na żywym masterze**: kalibracja i bramka z 2026-07-27
dotyczyły **innego kodu** (`fallback.py`, env `OLLAMA_PIHA_URL`) — na wdrożonym dotyczyły **innego kodu** (`fallback.py`, env `OLLAMA_PIHA_URL`) — na wdrożonym
e7625cd trzeba przejść testy A/B/C z `services/kb-query/README.md` oraz bramkę e7625cd trzeba przejść testy A/B/C z `kb/services/kb-query.md` oraz bramkę
`retrieval_eval.py --transport http` (po S1): HTTP-equivalence przy SOLARIA-up `retrieval_eval.py --transport http` (po S1): HTTP-equivalence przy SOLARIA-up
(identyczne `dist`) i sol-down (Δ≤epsilon, kolejność top-k identyczna; baseline (identyczne `dist`) i sol-down (Δ≤epsilon, kolejność top-k identyczna; baseline
z 27.07: Δ~3e-4). Symulacja wg README: `EMBED_PRIMARY_URL=http://192.0.2.1:11434` z 27.07: Δ~3e-4). Symulacja wg README: `EMBED_PRIMARY_URL=http://192.0.2.1:11434`

View file

@ -68,7 +68,7 @@ links: []
### 1.3 PIHA — budżet RAM (istotne dla decyzji D2 / lokalnego fallbacku) ### 1.3 PIHA — budżet RAM (istotne dla decyzji D2 / lokalnego fallbacku)
- Audyt `docs/infra/piha-slim-audit-2026-07-02.md`: po "bezpiecznym usuń" - Audyt `kb/audits/piha-slim-2026-07-02.md`: po "bezpiecznym usuń"
(elasticsearch+diskover+stary llm-gateway) available rosło z **2.9Gi do ~3.8Gi** (elasticsearch+diskover+stary llm-gateway) available rosło z **2.9Gi do ~3.8Gi**
(na 8 GB total, +4 GB swap). To jest **jedyna zweryfikowana liczba w repo i ma (na 8 GB total, +4 GB swap). To jest **jedyna zweryfikowana liczba w repo i ma
3 tygodnie** — od tego dnia na PIHA doszły (GitOps, z `mem_limit`): paperless+db+broker 3 tygodnie** — od tego dnia na PIHA doszły (GitOps, z `mem_limit`): paperless+db+broker
@ -97,7 +97,7 @@ domeny `*.kapala.org`:
(cert #51 *.okit.pl, cert osobny dla *.kapala.org — sesje ją tylko konfigurują (cert #51 *.okit.pl, cert osobny dla *.kapala.org — sesje ją tylko konfigurują
ręcznie/SQL-em, nigdy nie deployują z repo). kb-query dogania się do tego samego ręcznie/SQL-em, nigdy nie deployują z repo). kb-query dogania się do tego samego
wzorca: nowy vhost w `npm@PIHA`, TLS z **już istniejącego** wildcard `*.kapala.org` wzorca: nowy vhost w `npm@PIHA`, TLS z **już istniejącego** wildcard `*.kapala.org`
(pokrywa `paper.`/`cloud.`/`vikunja.kapala.org` — `docs/kb/modules/DECYZJE-do-podjecia.md` (pokrywa `paper.`/`cloud.`/`vikunja.kapala.org` — `kb/decisions/kb-dokumenty-otwarte.md`
#6) — **żaden nowy certyfikat nie jest potrzebny**. #6) — **żaden nowy certyfikat nie jest potrzebny**.
- **DNS — dwie warstwy, obie trzeba dotknąć** (lekcja `okit-cloudflare-migracja.md` - **DNS — dwie warstwy, obie trzeba dotknąć** (lekcja `okit-cloudflare-migracja.md`
§"WAZNE: split-horizon DNS"): (a) Cloudflare rekord A → Tailscale IP PIHA §"WAZNE: split-horizon DNS"): (a) Cloudflare rekord A → Tailscale IP PIHA
@ -261,7 +261,7 @@ przed backfillem" z fazy 3 §3.1 (zmierz, obejrzyj, dopiero wtedy zaufaj progowi
### Decyzja 3 — Linki do źródeł: paperless vs gmail ### Decyzja 3 — Linki do źródeł: paperless vs gmail
**Paperless**: URL do dokumentu — **do zweryfikowania na żywym Paperless przed **Paperless**: URL do dokumentu — **do zweryfikowania na żywym Paperless przed
implementacją** (repo nie ma zapisanego przykładu, `docs/kb/modules/02-paperless-service.md` implementacją** (repo nie ma zapisanego przykładu, `kb/phases/kb-m2-paperless.md`
dokumentuje tylko subdomenę, nie ścieżkę). Kandydat wg konwencji paperless-ngx UI: dokumentuje tylko subdomenę, nie ścieżkę). Kandydat wg konwencji paperless-ngx UI:
`https://paper.kapala.org/documents/<id>/details` (Angular routing) — `envelope_id` `https://paper.kapala.org/documents/<id>/details` (Angular routing) — `envelope_id`
`paperless:<id>` już niesie surowy `<id>` do wstawienia. Krok implementacji: jeden `paperless:<id>` już niesie surowy `<id>` do wstawienia. Krok implementacji: jeden
@ -471,7 +471,7 @@ Jedna strona (Jinja2 template + vanilla JS + CSS, serwowane z tego samego FastAP
- Pole zapytania + submit (Enter albo przycisk). - Pole zapytania + submit (Enter albo przycisk).
- Wyniki grupowane po `envelope_id` (dokument), w obrębie dokumentu chunki - Wyniki grupowane po `envelope_id` (dokument), w obrębie dokumentu chunki
posortowane po `dist`. posortowane po `dist`.
- Kolorowanie progów (progi z fazy 3, `docs/kb/modules/05-faza3-plan.md` §1.2, - Kolorowanie progów (progi z fazy 3, `kb/phases/kb-m5-faza3.md` §1.2,
zweryfikowane bramką): `dist < 0.45` zielony, `0.450.55` żółty, `> 0.55` zweryfikowane bramką): `dist < 0.45` zielony, `0.450.55` żółty, `> 0.55`
**nie renderować wyniku**, tylko komunikat "brak odpowiedzi w KB" (żółta/czerwona **nie renderować wyniku**, tylko komunikat "brak odpowiedzi w KB" (żółta/czerwona
strefa nadal renderuje wynik z ostrzeżeniem wizualnym; czerwona = brak sensownego strefa nadal renderuje wynik z ostrzeżeniem wizualnym; czerwona = brak sensownego

View file

@ -40,7 +40,7 @@ historia incydentów, out-of-band watchdog.
mózg NIETKNIĘTY, debounce per-alert (klucz alertname:node w state.json). 12 testów pass. mózg NIETKNIĘTY, debounce per-alert (klucz alertname:node w state.json). 12 testów pass.
PENDING zamknięty 2026-07-02: poll POTWIERDZONY reconem (obraz zbudowany po `62d6fc0`, PENDING zamknięty 2026-07-02: poll POTWIERDZONY reconem (obraz zbudowany po `62d6fc0`,
`PROMETHEUS_URL` w `.env` i w env kontenera, zero poll failed) — patrz `PROMETHEUS_URL` w `.env` i w env kontenera, zero poll failed) — patrz
`docs/infra/inventory-verify-2026-07-02.md`. `kb/subsystems/fleet-inventory-verify.md`.
✅ END-TO-END UDOWODNIONE 2026-07-06 (Etap 0 cutoveru): tor Prometheus → ✅ END-TO-END UDOWODNIONE 2026-07-06 (Etap 0 cutoveru): tor Prometheus →
watchdog → Telegram potwierdzony w produkcji testem `AlertTestEtap0` watchdog → Telegram potwierdzony w produkcji testem `AlertTestEtap0`
(firing → log polla → Telegram → rollback) — patrz `docs/sessions/2026-07-06.md`. (firing → log polla → Telegram → rollback) — patrz `docs/sessions/2026-07-06.md`.

View file

@ -164,7 +164,7 @@ Skutek uboczny do zaakceptowania świadomie: syntetyczne `node_stale`/
wyłączeniu **wcześniej, ale nie liczniej** — te eventy już dziś powstają co noc wyłączeniu **wcześniej, ale nie liczniej** — te eventy już dziś powstają co noc
(21:32/21:39 dla lustro, każdorazowo dla solaria). Cutover nie zwiększa wolumenu (21:32/21:39 dla lustro, każdorazowo dla solaria). Cutover nie zwiększa wolumenu
alertów. Docelowe wyciszenie planowych okien off to wątek anomaly-detection alertów. Docelowe wyciszenie planowych okien off to wątek anomaly-detection
z backlogu (`docs/backlog.md:390-406`) — **niezależny od cutoveru i nieblokujący**; z backlogu (`kb/phases/backlog.md:390-406`) — **niezależny od cutoveru i nieblokujący**;
`NodeDown` dla solaria/lustro słusznie pozostaje wyłączony. `NodeDown` dla solaria/lustro słusznie pozostaje wyłączony.
### Rekomendowany mapping (potwierdzenie rekomendacji z recon F/Etap 2) ### Rekomendowany mapping (potwierdzenie rekomendacji z recon F/Etap 2)

View file

@ -9,7 +9,7 @@ links: []
# Plan naprawy subsystemu A (control-plane) — 2026-07-28 # Plan naprawy subsystemu A (control-plane) — 2026-07-28
Kontekst: docs/architecture/RECON-multiagent-2026-07-27.md. Decyzje bazowe: Kontekst: kb/subsystems/recon-multiagent.md. Decyzje bazowe:
- Flota dzieli się na dwa subsystemy. A = utrzymaniowy (control-plane, node-agenty, - Flota dzieli się na dwa subsystemy. A = utrzymaniowy (control-plane, node-agenty,
self-healing) — ten plan. B = zleceniowy (dyspozytor + Telegram + KB + HA + self-healing) — ten plan. B = zleceniowy (dyspozytor + Telegram + KB + HA +
homelab-ops) — prowadzony w osobnym projekcie, poza tym planem. homelab-ops) — prowadzony w osobnym projekcie, poza tym planem.

View file

@ -12,7 +12,7 @@ links:
## First-time deployment ## First-time deployment
See **[DEPLOY.md](DEPLOY.md)** for the full procedure: HA token creation, See **[DEPLOY.md](ha-diag-agent-deploy.md)** for the full procedure: HA token creation,
per-host `.env` config, deploy commands, verification steps, 48h shadow-mode per-host `.env` config, deploy commands, verification steps, 48h shadow-mode
observation, and rollback. observation, and rollback.

View file

@ -13,7 +13,7 @@ links:
## Deploy (PIHA) ## Deploy (PIHA)
0. Prerequisite: `ollama-piha` deployed and `bge-m3` pulled — see 0. Prerequisite: `ollama-piha` deployed and `bge-m3` pulled — see
`services/ollama-piha/README.md` (the pull is a **manual** deploy step). `kb/services/ollama-piha.md` (the pull is a **manual** deploy step).
1. `git pull` on PIHA (`~/homelab-codex-ws`). 1. `git pull` on PIHA (`~/homelab-codex-ws`).
2. `cp services/kb-query/env.example services/kb-query/.env` and fill in the 2. `cp services/kb-query/env.example services/kb-query/.env` and fill in the
real `KB_DSN` password (the template already sets `EMBED_FALLBACK_URL`). real `KB_DSN` password (the template already sets `EMBED_FALLBACK_URL`).

View file

@ -97,7 +97,7 @@ bind-mount the existing model directory.**
docker exec ollama ollama ps docker exec ollama ollama ps
``` ```
3. Embeddings endpoint + vector dimension (deferred check from 3. Embeddings endpoint + vector dimension (deferred check from
`docs/kb/modules/05-faza2-plan.md` §6 step 2): `kb/phases/kb-m5-faza2.md` §6 step 2):
```bash ```bash
curl -s http://localhost:11434/api/embeddings -d '{"model":"bge-m3","prompt":"test"}' \ curl -s http://localhost:11434/api/embeddings -d '{"model":"bge-m3","prompt":"test"}' \
| python3 -c "import json,sys; v=json.load(sys.stdin)['embedding']; print(len(v))" | python3 -c "import json,sys; v=json.load(sys.stdin)['embedding']; print(len(v))"
@ -145,7 +145,7 @@ SOLARIA:
- Given the missing driver, the cutover proceeded **in CPU-only mode**: the - Given the missing driver, the cutover proceeded **in CPU-only mode**: the
`deploy.resources` GPU reservation was commented out in `deploy.resources` GPU reservation was commented out in
`services/ollama/docker-compose.yml` (commit `f57a01a`), and the driver fix `services/ollama/docker-compose.yml` (commit `f57a01a`), and the driver fix
was filed as a backlog item (see `docs/backlog.md`) blocking the module 5 was filed as a backlog item (see `kb/phases/backlog.md`) blocking the module 5
mail-embedding phase. mail-embedding phase.
- **2026-07-16: driver fixed.** Installed `nvidia-driver-595-open` from the - **2026-07-16: driver fixed.** Installed `nvidia-driver-595-open` from the
distro repository — not the old `ppa:graphics-drivers/ppa` (jammy), which distro repository — not the old `ppa:graphics-drivers/ppa` (jammy), which

View file

@ -23,7 +23,7 @@ links:
wildcard `*.kapala.org` już pokrywa tę subdomenę, nowy cert niepotrzebny. wildcard `*.kapala.org` już pokrywa tę subdomenę, nowy cert niepotrzebny.
Plus vhost w npm@PIHA (HTTPS → `192.168.31.5:8210`, Advanced puste). Plus vhost w npm@PIHA (HTTPS → `192.168.31.5:8210`, Advanced puste).
6. `docker compose up -d` + `./healthcheck.sh` + testowy login OIDC. 6. `docker compose up -d` + `./healthcheck.sh` + testowy login OIDC.
7. Export NFS dla workera (patrz `services/paperless-worker/README.md`) — 7. Export NFS dla workera (patrz `kb/services/paperless-worker.md`) —
dopiero przy module 3. dopiero przy module 3.
8. Wpis w `hosts/piha/services.yaml` (dopiero przy deployu — wcześniej 8. Wpis w `hosts/piha/services.yaml` (dopiero przy deployu — wcześniej
supervisor widziałby drift dla nieistniejącego serwisu). supervisor widziałby drift dla nieistniejącego serwisu).

View file

@ -64,4 +64,4 @@ Weryfikacja po deployu: `./healthcheck.sh` robi test zapisu na mount.
`inventory/topology.yaml` (obecnie SOLARIA ma tam tylko `node-agent`) — `inventory/topology.yaml` (obecnie SOLARIA ma tam tylko `node-agent`) —
bez tego supervisor/observer nie widzą tego serwisu w desired-state, więc bez tego supervisor/observer nie widzą tego serwisu w desired-state, więc
drift między `hosts/solaria/services.yaml` a rzeczywistością nie jest drift między `hosts/solaria/services.yaml` a rzeczywistością nie jest
wykrywany. Patrz `docs/backlog.md`. wykrywany. Patrz `kb/phases/backlog.md`.

View file

@ -5,7 +5,8 @@ visibility: private
status: active status: active
updated: 2026-08-03 updated: 2026-08-03
stub: true stub: true
links: [] links:
- ../subsystems/control-plane.md
--- ---
# control-plane # control-plane

View file

@ -10,7 +10,7 @@ links:
# ha-mcp — read-only MCP server for Home Assistant # ha-mcp — read-only MCP server for Home Assistant
**Status: phase 2a** of `services/home-assistant/DESIGN.md` — own minimal MCP **Status: phase 2a** of `kb/decisions/ha-configs-as-code.md` — own minimal MCP
server (the alternative, adopting `hass-mcp`, was the other option in that server (the alternative, adopting `hass-mcp`, was the other option in that
document's Open questions; operator decision 2026-07-30: build our own). document's Open questions; operator decision 2026-07-30: build our own).
@ -38,7 +38,7 @@ in this server that changes anything in Home Assistant:
**The write path back into Home Assistant is unchanged and lives elsewhere:** **The write path back into Home Assistant is unchanged and lives elsewhere:**
edit `services/home-assistant/config/<instance>/` in the repo, then edit `services/home-assistant/config/<instance>/` in the repo, then
`scripts/ha/deploy.sh <instance>` (drift-abort → `check_config` → write → `scripts/ha/deploy.sh <instance>` (drift-abort → `check_config` → write →
verify). See `services/home-assistant/DESIGN.md`, "Sync model" and verify). See `kb/decisions/ha-configs-as-code.md`, "Sync model" and
"Validation gate". Nothing in this server bypasses that, and nothing in this "Validation gate". Nothing in this server bypasses that, and nothing in this
server should ever learn to. server should ever learn to.
@ -140,7 +140,7 @@ down — you then get `live_error` instead of `live`.
## Why `unavailable` is in every result ## Why `unavailable` is in every result
The 2026-07-23 audit (`services/home-assistant/docs/audyt-automatyzacji-2026-07-23.md`, The 2026-07-23 audit (`kb/audits/ha-automatyzacje-2026-07-23.md`,
1.21.4) traced ~15 silently broken automations to dead sensors: a condition 1.21.4) traced ~15 silently broken automations to dead sensors: a condition
on an `unavailable` entity is simply never true, and HA reports no error. So on an `unavailable` entity is simply never true, and HA reports no error. So
every entity view here carries an explicit `unavailable: true` plus every entity view here carries an explicit `unavailable: true` plus

View file

@ -15,7 +15,7 @@ Assistant instance: the `homeassistant5` container on piha, wound down
2026-07. It is kept for historical reference only — e.g. recovering the 2026-07. It is kept for historical reference only — e.g. recovering the
logic of an old automation — not as a live or deployable instance. logic of an old automation — not as a live or deployable instance.
See `services/home-assistant/DESIGN.md`, "Incident log" (2026-07-22) for See `kb/decisions/ha-configs-as-code.md`, "Incident log" (2026-07-22) for
why this instance exists separately from the canonical `ken` (now the why this instance exists separately from the canonical `ken` (now the
Home Assistant OS instance on the RPi4 at 192.168.31.7): this container Home Assistant OS instance on the RPi4 at 192.168.31.7): this container
kept running after the real migration and was firing automations in kept running after the real migration and was firing automations in

View file

@ -11,7 +11,7 @@ links:
# documents-ingest # documents-ingest
One-shot job CLI, Phase 1 of module 5 (`docs/kb/modules/05-documents-ingest.md`, One-shot job CLI, Phase 1 of module 5 (`kb/phases/kb-m5-documents-ingest.md`,
"Domkniecie dlugu z maili"). Extracts a **sample** of PDF attachments from the "Domkniecie dlugu z maili"). Extracts a **sample** of PDF attachments from the
Gmail `.eml` archive (already indexed in the `envelope` table of kb-postgres) Gmail `.eml` archive (already indexed in the `envelope` table of kb-postgres)
and drops them into Paperless' `consume/` directory so Paperless does the OCR and drops them into Paperless' `consume/` directory so Paperless does the OCR
@ -98,7 +98,7 @@ skipped.
`<YYYY-MM-DD>_<sanitized-filename>_<hash8>.pdf`. `<YYYY-MM-DD>_<sanitized-filename>_<hash8>.pdf`.
Files are written with a best-effort `chown` to uid:gid `1000:1000` (the Files are written with a best-effort `chown` to uid:gid `1000:1000` (the
Paperless container's `USERMAP_UID/GID`, see `services/paperless/README.md`) Paperless container's `USERMAP_UID/GID`, see `kb/services/paperless.md`)
so Paperless can read them. If the chown fails (e.g. the job isn't running as so Paperless can read them. If the chown fails (e.g. the job isn't running as
root/uid 1000), a warning is logged but the run continues — the write itself root/uid 1000), a warning is logged but the run continues — the write itself
already succeeded; fix ownership/perms on `consume/` separately if needed. already succeeded; fix ownership/perms on `consume/` separately if needed.

View file

@ -10,7 +10,7 @@ links:
# gmail-header-backfill # gmail-header-backfill
One-shot job, module 5 phase 2 backfill (`docs/kb/modules/05-faza2-plan.md`, §5). One-shot job, module 5 phase 2 backfill (`kb/phases/kb-m5-faza2.md`, §5).
Backfills `{"type": "headers", ...}` onto the 225 030 existing `source='gmail'` Backfills `{"type": "headers", ...}` onto the 225 030 existing `source='gmail'`
envelope rows in kb-postgres, which today carry only an attachment manifest envelope rows in kb-postgres, which today carry only an attachment manifest
(`{"type": "attachment", ...}`) — no `from`/`to`/`cc`/`delivered_to`/`subject` (`{"type": "attachment", ...}`) — no `from`/`to`/`cc`/`delivered_to`/`subject`

View file

@ -10,7 +10,7 @@ links:
# mail-body-ingest # mail-body-ingest
Module 5, faza mailowa (`docs/kb/modules/05-faza-mailowa-plan.md`, §5, Krok 2). Second full Module 5, faza mailowa (`kb/phases/kb-m5-faza-mailowa.md`, §5, Krok 2). Second full
pass over the gmail `.eml` archive — `gmail-bulk-import` deliberately skipped inline pass over the gmail `.eml` archive — `gmail-bulk-import` deliberately skipped inline
`text/plain`/`text/html` parts (`_parse_attachments` does `continue` on them); this job reads `text/plain`/`text/html` parts (`_parse_attachments` does `continue` on them); this job reads
exactly the content that gap left out, chunks it, embeds it, and inserts it into exactly the content that gap left out, chunks it, embeds it, and inserts it into

View file

@ -98,7 +98,7 @@ Indexes:
## Schema contract ## Schema contract
The `envelope` table is the frozen cross-source envelope (see `docs/kb/kb-00-overview.md` §Zasady przekrojowe). Adding columns is OK; removing or renaming existing ones is NOT. The `envelope` table is the frozen cross-source envelope (see `kb/subsystems/kb-overview.md` §Zasady przekrojowe). Adding columns is OK; removing or renaming existing ones is NOT.
Future migrations go in `init/` as `002_*.sql`, `003_*.sql`, …. Postgres runs `initdb` scripts only on a fresh volume — for existing instances apply migrations with `psql` directly. Future migrations go in `init/` as `002_*.sql`, `003_*.sql`, …. Postgres runs `initdb` scripts only on a fresh volume — for existing instances apply migrations with `psql` directly.

View file

@ -167,4 +167,4 @@ existed.
- Calibration verdict for the fallback (plan §5 steps 45: live PIHA - Calibration verdict for the fallback (plan §5 steps 45: live PIHA
measurements → keep/tune/degrade decision) — the mechanism is built and measurements → keep/tune/degrade decision) — the mechanism is built and
default-on when `EMBED_FALLBACK_URL` is set; the measurements are the default-on when `EMBED_FALLBACK_URL` is set; the measurements are the
operator's post-deploy step (see `services/ollama-piha/README.md`). operator's post-deploy step (see `kb/services/ollama-piha.md`).

View file

@ -11,9 +11,9 @@ superseded_by: "hosts/chelsty-infra/runtime/mosquitto/ (chelsty) + host systemd
# Mosquitto MQTT Broker — NOT DEPLOYED / LEGACY # Mosquitto MQTT Broker — NOT DEPLOYED / LEGACY
> **Status (2026-07-28, truth cleanup):** this manifest matches **nothing that > **Status (2026-07-28, truth cleanup):** this manifest matches **nothing that
> actually runs** (recon `docs/architecture/RECON-multiagent-2026-07-27.md`, C8). > actually runs** (recon `kb/subsystems/recon-multiagent.md`, C8).
> The broker on **vps** is part of the legacy ai-cluster stack (being > The broker on **vps** is part of the legacy ai-cluster stack (being
> decommissioned, see `docs/architecture/ai-cluster-LEGACY.md`); the broker on > decommissioned, see `kb/decisions/ai-cluster-legacy.md`); the broker on
> **piha** is a host systemd mosquitto (OS package) with no repo definition; > **piha** is a host systemd mosquitto (OS package) with no repo definition;
> **chelsty** has its own config under `hosts/chelsty-infra/runtime/mosquitto/`. > **chelsty** has its own config under `hosts/chelsty-infra/runtime/mosquitto/`.
> Do not deploy from this directory. Kept until the MQTT topology decision > Do not deploy from this directory. Kept until the MQTT topology decision

View file

@ -11,7 +11,7 @@ links:
# Nextcloud (drive / WebDAV) # Nextcloud (drive / WebDAV)
Drugi adapter dokumentów filaru KB #2 (moduł 4, `docs/kb/modules/04-nextcloud.md`): Drugi adapter dokumentów filaru KB #2 (moduł 4, `kb/phases/kb-m4-nextcloud.md`):
zamiennik Google Drive — dowolne pliki + sync telefon/desktop, źródło dla zamiennik Google Drive — dowolne pliki + sync telefon/desktop, źródło dla
ingestu KB (moduł 5) przez WebDAV. ingestu KB (moduł 5) przez WebDAV.

View file

@ -46,5 +46,5 @@ SOLARIA with a ~30 s cache and only sends embeds here while SOLARIA is down.
kb-query verifies at first use that this backend actually serves `bge-m3` kb-query verifies at first use that this backend actually serves `bge-m3`
(`/api/tags`) and refuses to embed against a mismatched model. Configuration: (`/api/tags`) and refuses to embed against a mismatched model. Configuration:
`EMBED_FALLBACK_URL=http://192.168.31.5:11434` in `services/kb-query/.env`. `EMBED_FALLBACK_URL=http://192.168.31.5:11434` in `services/kb-query/.env`.
See `services/kb-query/README.md` for the fallback verification plan (tests See `kb/services/kb-query.md` for the fallback verification plan (tests
A/B/C). A/B/C).

View file

@ -10,7 +10,7 @@ links:
# Paperless OCR worker (SOLARIA) # Paperless OCR worker (SOLARIA)
Ciężki OCR filaru KB #2 (moduł 3, `docs/kb/modules/03-paperless-ocr-worker.md`). Ciężki OCR filaru KB #2 (moduł 3, `kb/phases/kb-m3-ocr-worker.md`).
Ten sam obraz co `services/paperless/`, ale z nadpisanym poleceniem — działa Ten sam obraz co `services/paperless/`, ale z nadpisanym poleceniem — działa
**wyłącznie** jako celery worker podpięty do brokera/bazy paperless@PIHA, **wyłącznie** jako celery worker podpięty do brokera/bazy paperless@PIHA,
ze storage widzianym przez NFS z PIHA. Realizuje wzorzec kb-02 ze storage widzianym przez NFS z PIHA. Realizuje wzorzec kb-02

View file

@ -11,7 +11,7 @@ links:
# Paperless-ngx (serwis, PIHA) # Paperless-ngx (serwis, PIHA)
Serwis dokumentów filaru KB #2 (moduł 2, `docs/kb/modules/02-paperless-service.md`): Serwis dokumentów filaru KB #2 (moduł 2, `kb/phases/kb-m2-paperless.md`):
UI + API + Postgres + Redis. Always-on na PIHA. Ciężki OCR wykonuje osobny worker UI + API + Postgres + Redis. Always-on na PIHA. Ciężki OCR wykonuje osobny worker
na SOLARIA (`services/paperless-worker/`, moduł 3) — tu zostaje tylko wolny na SOLARIA (`services/paperless-worker/`, moduł 3) — tu zostaje tylko wolny
fallback (1 worker × 1 wątek). fallback (1 worker × 1 wątek).

View file

@ -15,9 +15,9 @@ This document defines the operating procedures, constraints, and interaction pro
1. **Read-Only by Default**: Agents should assume read-only access to the `/opt/homelab` runtime unless explicitly executing an approved action. 1. **Read-Only by Default**: Agents should assume read-only access to the `/opt/homelab` runtime unless explicitly executing an approved action.
2. **Git as Authority**: The repository on **SATURN** is the source of truth. Agents must not modify the runtime state on nodes directly without corresponding (or pending) Git state, unless it's an emergency mitigation. 2. **Git as Authority**: The repository on **SATURN** is the source of truth. Agents must not modify the runtime state on nodes directly without corresponding (or pending) Git state, unless it's an emergency mitigation.
3. **Human-in-the-Loop (HIL)**: All destructive or structural changes (restarts, deployments, config changes) must follow the [Action Approval Model](../services/agent-system/action-model.md). 3. **Human-in-the-Loop (HIL)**: All destructive or structural changes (restarts, deployments, config changes) must follow the [Action Approval Model](action-approval-model.md).
4. **Idempotency**: All scripts and actions proposed or executed by agents MUST be idempotent. 4. **Idempotency**: All scripts and actions proposed or executed by agents MUST be idempotent.
5. **Context-Awareness**: Agents MUST read the `README.md` and `docs/agents.md` at the start of every session to align with current infrastructure standards. 5. **Context-Awareness**: Agents MUST read the `README.md` and `kb/subsystems/agent-operating-procedures.md` at the start of every session to align with current infrastructure standards.
## 2. Agent Roles ## 2. Agent Roles

View file

@ -5,6 +5,7 @@ visibility: private
status: deprecated status: deprecated
updated: 2026-05-27 updated: 2026-05-27
links: links:
- ../services/control-plane.md
- ../runbooks/control-plane-deploy-recovery.md - ../runbooks/control-plane-deploy-recovery.md
superseded_by: "przepisany tor redeploy, commity da151fc/79bfe8c 2026-08-03" superseded_by: "przepisany tor redeploy, commity da151fc/79bfe8c 2026-08-03"
--- ---

View file

@ -11,7 +11,7 @@ links: []
Zebrano: 2026-07-02 ~15:20 CEST (read-only recon, zero zmian na nodach). Zebrano: 2026-07-02 ~15:20 CEST (read-only recon, zero zmian na nodach).
Metoda: ssh + `docker ps -a / inspect / logs`, `free/df/nproc/lscpu/lsblk`, `git branch/log` (odczyt), Metoda: ssh + `docker ps -a / inspect / logs`, `free/df/nproc/lscpu/lsblk`, `git branch/log` (odczyt),
`curl` do fleet-prometheus API. Porównanie z `docs/infra/inventory-2026-06-30.md` (23 rozjazdy) `curl` do fleet-prometheus API. Porównanie z `kb/subsystems/fleet-inventory.md` (23 rozjazdy)
oraz z repo na `master` (HEAD `22adfb1`). oraz z repo na `master` (HEAD `22adfb1`).
Dostępność nodów podczas weryfikacji: Dostępność nodów podczas weryfikacji:

View file

@ -615,7 +615,7 @@ No runtime state was touched.
**Legacy** **Legacy**
- `docs/architecture/ai-cluster-LEGACY.md`: ai-cluster is retired in place, - `kb/decisions/ai-cluster-legacy.md`: ai-cluster is retired in place,
not migrated (bus idle since 2026-06-09, C9); branch `task/ai-cluster-solaria` not migrated (bus idle since 2026-06-09, C9); branch `task/ai-cluster-solaria`
stays unmerged as documentation; surviving patterns listed; runtime stays unmerged as documentation; surviving patterns listed; runtime
retirement runbook (stop stack on vps, observe `free -m`, remove containers) retirement runbook (stop stack on vps, observe `free -m`, remove containers)

View file

@ -1,4 +1,4 @@
"""Shared chunker — module 5, phase mailowa, plan step 0 (docs/kb/modules/05-faza-mailowa-plan.md, """Shared chunker — module 5, phase mailowa, plan step 0 (kb/phases/kb-m5-faza-mailowa.md,
§3). Moved 1:1 out of `jobs/documents_ingest/chunk_embed.py` so both the paperless job and §3). Moved 1:1 out of `jobs/documents_ingest/chunk_embed.py` so both the paperless job and
`jobs/mail-body-ingest` chunk against the exact same tested logic instead of two implementations `jobs/mail-body-ingest` chunk against the exact same tested logic instead of two implementations
drifting apart (the phase-4 lesson for `retrieval.py` -> `packages/kb-retrieval`, applied again). drifting apart (the phase-4 lesson for `retrieval.py` -> `packages/kb-retrieval`, applied again).

View file

@ -71,7 +71,7 @@ def test_migration_002_references_envelope_with_cascade():
def test_migration_002_embedding_dimension_matches_bge_m3(): def test_migration_002_embedding_dimension_matches_bge_m3():
sql = (INIT_DIR / "002_chunks.sql").read_text() sql = (INIT_DIR / "002_chunks.sql").read_text()
# bge-m3 dense embedding dimension is 1024 (docs/kb/modules/05-faza2-plan.md §1.4) # bge-m3 dense embedding dimension is 1024 (kb/phases/kb-m5-faza2.md §1.4)
assert "VECTOR(1024)" in sql.upper() assert "VECTOR(1024)" in sql.upper()

View file

@ -1,4 +1,4 @@
"""Ollama embedding client -- module 5, phase 4, plan step 0 (docs/kb/modules/05-faza4-plan.md, """Ollama embedding client -- module 5, phase 4, plan step 0 (kb/phases/kb-m5-faza4.md,
§3, decision 1). Moved 1:1 out of `jobs/documents_ingest/chunk_embed.py` (`embed_chunk`, §3, decision 1). Moved 1:1 out of `jobs/documents_ingest/chunk_embed.py` (`embed_chunk`,
`_vector_literal`, `DEFAULT_MODEL`, `DEFAULT_OLLAMA_URL`) so both a venv-based host job `_vector_literal`, `DEFAULT_MODEL`, `DEFAULT_OLLAMA_URL`) so both a venv-based host job
(`documents-ingest`) and a long-lived Docker service (`kb-query`) can depend on the same tested (`documents-ingest`) and a long-lived Docker service (`kb-query`) can depend on the same tested
@ -8,7 +8,7 @@ client without the service image pulling in `jobs/`'s `anthropic` dependency and
health-check + circuit breaker (plan §2 decision 2) builds on, kept in this module so the HTTP health-check + circuit breaker (plan §2 decision 2) builds on, kept in this module so the HTTP
probing logic lives in exactly one place. probing logic lives in exactly one place.
`embed_batch` -- module 5, faza mailowa, plan Krok 1 (docs/kb/modules/05-faza-mailowa-plan.md, `embed_batch` -- module 5, faza mailowa, plan Krok 1 (kb/phases/kb-m5-faza-mailowa.md,
§4, decision 5): `/api/embed` with `input` as a list, batch 64 measured live at ~8-18 ms/chunk §4, decision 5): `/api/embed` with `input` as a list, batch 64 measured live at ~8-18 ms/chunk
vs ~150-200 ms/chunk sequential through `embed_chunk`'s `/api/embeddings` (plan §1.4). Used by vs ~150-200 ms/chunk sequential through `embed_chunk`'s `/api/embeddings` (plan §1.4). Used by
`jobs/mail-body-ingest` only -- `embed_chunk` stays the single-text path for kb-query (one query `jobs/mail-body-ingest` only -- `embed_chunk` stays the single-text path for kb-query (one query

View file

@ -1,12 +1,12 @@
"""Retrieval module -- module 5, phase 3, plan step 4 (docs/kb/modules/05-faza3-plan.md, §6). """Retrieval module -- module 5, phase 3, plan step 4 (kb/phases/kb-m5-faza3.md, §6).
Moved 1:1 into `packages/kb-retrieval` in phase 4 (docs/kb/modules/05-faza4-plan.md, §3, Moved 1:1 into `packages/kb-retrieval` in phase 4 (kb/phases/kb-m5-faza4.md, §3,
decision 1) so both `documents-ingest` (venv job) and `kb-query` (Docker service) share one decision 1) so both `documents-ingest` (venv job) and `kb-query` (Docker service) share one
tested module instead of the service image needing to pull in all of `jobs/documents-ingest`. tested module instead of the service image needing to pull in all of `jobs/documents-ingest`.
Three retrieval paths over the same corpus, sharing one query embedding (bge-m3, via Ollama): Three retrieval paths over the same corpus, sharing one query embedding (bge-m3, via Ollama):
- `flat_retrieve`: baseline -- ranks every active `document_chunk` row directly. This - `flat_retrieve`: baseline -- ranks every active `document_chunk` row directly. This
formalizes the pilot's ad hoc `/tmp/kbq.sh` query (docs/kb/eval/retrieval-pilot-2026-07-16.md) formalizes the pilot's ad hoc `/tmp/kbq.sh` query (kb/phases/kb-m5-eval-retrieval-pilot.md)
into a tested, versioned module instead of a script living only in a session transcript. into a tested, versioned module instead of a script living only in a session transcript.
- `cascade_retrieve`: pre-filters to the top-N `document_summary` matches for one configured - `cascade_retrieve`: pre-filters to the top-N `document_summary` matches for one configured
`model` (plan §2 decision 3, resolved 2026-07-17 as D3: `claude-haiku-4-5` is the compilation `model` (plan §2 decision 3, resolved 2026-07-17 as D3: `claude-haiku-4-5` is the compilation
@ -15,7 +15,7 @@ Three retrieval paths over the same corpus, sharing one query embedding (bge-m3,
-- it is an architecture test for the mail-scale corpus (225k envelopes, plan §1.1) where a -- it is an architecture test for the mail-scale corpus (225k envelopes, plan §1.1) where a
flat chunk scan stops being cheap. `eval/retrieval_eval.py` runs the quality gate (plan §6.2) flat chunk scan stops being cheap. `eval/retrieval_eval.py` runs the quality gate (plan §6.2)
that decides whether it becomes the default path. that decides whether it becomes the default path.
- `hybrid_retrieve` -- module 5, faza mailowa, plan Krok 3 (docs/kb/modules/05-faza-mailowa-plan.md, - `hybrid_retrieve` -- module 5, faza mailowa, plan Krok 3 (kb/phases/kb-m5-faza-mailowa.md,
§6, decision 6): mail (gmail) envelopes never get a `document_summary` (streszczenie maila §6, decision 6): mail (gmail) envelopes never get a `document_summary` (streszczenie maila
would usually be longer than the mail itself -- decision 6's rejected-summaries reasoning), so would usually be longer than the mail itself -- decision 6's rejected-summaries reasoning), so
they are invisible to the cascade's stage 1 pre-filter. Hybrid runs the cascade for sources that they are invisible to the cascade's stage 1 pre-filter. Hybrid runs the cascade for sources that

View file

@ -98,7 +98,7 @@ class _FakeSession:
class TestDefaults: class TestDefaults:
def test_plan_start_values(self): def test_plan_start_values(self):
# plan §6.1: "Start: N=10, k=5" -- a regression guard against silently drifting off # plan §6.1: "Start: N=10, k=5" -- a regression guard against silently drifting off
# the value the quality gate (docs/kb/modules/05-faza3-plan.md §6.2) was run against. # the value the quality gate (kb/phases/kb-m5-faza3.md §6.2) was run against.
assert DEFAULT_N == 10 assert DEFAULT_N == 10
assert DEFAULT_K == 5 assert DEFAULT_K == 5

View file

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Write path: repo -> HA instance, for the "api" adapter only (see # Write path: repo -> HA instance, for the "api" adapter only (see
# services/home-assistant/DESIGN.md, "Deploy path: adapter per instance", # kb/decisions/ha-configs-as-code.md, "Deploy path: adapter per instance",
# "Sync model", "Validation gate"). # "Sync model", "Validation gate").
# #
# Scope: automations/scripts/scenes only. Dashboards and helpers are # Scope: automations/scripts/scenes only. Dashboards and helpers are

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Read-only import of one Home Assistant instance's /config tree (plus a # Read-only import of one Home Assistant instance's /config tree (plus a
# curated .storage/* export and an /api/states fixture snapshot) into this # curated .storage/* export and an /api/states fixture snapshot) into this
# repo, normalized and split per services/home-assistant/DESIGN.md. # repo, normalized and split per kb/decisions/ha-configs-as-code.md.
# #
# This script NEVER writes to the HA instance. It is idempotent: re-running # This script NEVER writes to the HA instance. It is idempotent: re-running
# against an unchanged instance produces no diff under # against an unchanged instance produces no diff under

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Deploy path (repo -> instance) for the HA "api" adapter — see """Deploy path (repo -> instance) for the HA "api" adapter — see
services/home-assistant/DESIGN.md, "Sync model" and "Validation gate". kb/decisions/ha-configs-as-code.md, "Sync model" and "Validation gate".
Scope: automations/scripts/scenes only (the domains reachable via Scope: automations/scripts/scenes only (the domains reachable via
`/api/config/<domain>/config/<id>`). Dashboards and helpers are WS-only `/api/config/<domain>/config/<id>`). Dashboards and helpers are WS-only

View file

@ -5,7 +5,7 @@ adapter per instance").
Every entrypoint here takes a *token_path*, never a token value, and reads Every entrypoint here takes a *token_path*, never a token value, and reads
the token from disk itself. The bearer token must never appear as a process the token from disk itself. The bearer token must never appear as a process
argv (visible to any local user via `ps`) or in a log line see DESIGN.md, argv (visible to any local user via `ps`) or in a log line see DESIGN.md,
"Tokens", and the api-adapter requirements in docs/backlog.md. Callers "Tokens", and the api-adapter requirements in kb/phases/backlog.md. Callers
needing the token value in-process (e.g. the WebSocket client in needing the token value in-process (e.g. the WebSocket client in
ha_ws.py) should call read_token() directly rather than shelling out. ha_ws.py) should call read_token() directly rather than shelling out.

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Write-capable REST client for the HA "api" adapter's deploy path (see """Write-capable REST client for the HA "api" adapter's deploy path (see
services/home-assistant/DESIGN.md, "Sync model", "Validation gate"). kb/decisions/ha-configs-as-code.md, "Sync model", "Validation gate").
Deliberately kept out of ha_api.py, whose module docstring guarantees that Deliberately kept out of ha_api.py, whose module docstring guarantees that
module is read-only by construction the import path relies on that module is read-only by construction the import path relies on that

View file

@ -9,7 +9,7 @@ commands this module ever sends are `auth` and whatever `*_list`/
has no method that issues a create/update/delete command. has no method that issues a create/update/delete command.
Depends on the `websocket-client` PyPI package (import name `websocket`), Depends on the `websocket-client` PyPI package (import name `websocket`),
which is not in the stdlib. See services/home-assistant/README.md, which is not in the stdlib. See kb/runbooks/home-assistant-deploy.md,
"WebSocket dependency", for the install command. Importing this module "WebSocket dependency", for the install command. Importing this module
raises ImportError with an actionable message if it's missing, instead of raises ImportError with an actionable message if it's missing, instead of
the default traceback, so the api adapter can surface one clear line the default traceback, so the api adapter can surface one clear line
@ -25,7 +25,7 @@ except ImportError as exc: # pragma: no cover - exercised via import.sh error p
"the 'websocket-client' package is required for the api adapter's " "the 'websocket-client' package is required for the api adapter's "
"dashboard/registry/helper export (HA's WebSocket API) — install it " "dashboard/registry/helper export (HA's WebSocket API) — install it "
"with 'sudo apt install python3-websocket' or 'pip install --user " "with 'sudo apt install python3-websocket' or 'pip install --user "
"websocket-client' (see services/home-assistant/README.md, " "websocket-client' (see kb/runbooks/home-assistant-deploy.md, "
"'WebSocket dependency')" "'WebSocket dependency')"
) from exc ) from exc

Some files were not shown because too many files have changed in this diff Show more