diff --git a/docs/sessions/2026-08-05-kb-mail-batching.md b/docs/sessions/2026-08-05-kb-mail-batching.md new file mode 100644 index 0000000..e7a7ed9 --- /dev/null +++ b/docs/sessions/2026-08-05-kb-mail-batching.md @@ -0,0 +1,87 @@ +--- +okf: "0.1" +type: session-log +visibility: private +status: active +updated: 2026-08-05 +links: [] +--- + +# Sesja 2026-08-05 — batching embed (start fazy mailowej) + +## Weryfikacja zaległości + +- **Uninstall natywnego `ollama.service` na PIHA — POTWIERDZONY.** Unit i binarka nie + istnieją. +- **Session log fazy 4 istniał już na masterze** (`e619c00`). Zgłoszony brak był fałszywym + alarmem z niedociągniętego working tree na SOLARII. +- **`task/prune-fix` (R1–R3 + M1 VPS) gotowy do review** w subsystemie A — `0526af1`, + 285 insertions, z testami. + +## Task `kb-mail-batching` + +Zmergowany do mastera: `02a0079` + `75116ad`. + +### Bug blokujący Etap B (znaleziony i naprawiony) + +Goły `builtins.TimeoutError` z wyczerpanego `aiohttp` `ClientTimeout` **nie był łapany** +przez `flush_embed_buffer` — obsługa łapała wyłącznie `ClientError`. Skutek: zawieszona +Ollama (failure mode „przyjmuje połączenie i milczy") wywalała cały run, bez breakera +i bez flushu. Klasy przejściowe wyliczone są teraz jawnie w `TRANSIENT_EMBED_ERRORS`. + +### `embed_batch_resilient()` + +- Retry z backoffem wykładniczym. +- Po wyczerpaniu retry — probe `/api/tags`: + - backend **żywy** → bisekcja izolująca trujący chunk, + - backend **martwy** → `gave_up`, bez bisekcji. + +### Semantyka breakera (zmiana) + +Breaker liczy **give-upy** (backend down wg probe), nie nieudane batche. Porażka częściowa +nie przesuwa licznika. Zmiana znaczenia `--max-embed-failures` opisana w +`kb/phases/kb-m5-faza-mailowa.md` §9. + +### Parametryzacja i metryki + +- Flagi: `--batch-size`, `--embed-retries`, `--embed-backoff`, `--embed-timeout` + (env `MAIL_INGEST_*`). +- Metryka `embed_ms_per_chunk`. +- Wiersze zembedowane w umierającym batchu są commitowane przed abortem. + +### Decyzja: brak fallbacku SOLARIA→PIHA dla backfillu + +Świadomie **nie powstaje** — 790 ms/embed na CPU × 271k ≈ 60 h na współdzielonym nodzie. +Tor online (`embed_router`) zachowuje fallback. Rozdział torów udokumentowany w docstringu +`embed.py` / `embed_batch` oraz w `kb/services/job-mail-body-ingest.md`. + +### Benchmark `mail-body-ingest-bench` + +Read-only (SELECT + inferencja). Wyniki na SOLARII (bge-m3, GPU), próbka 640 chunków +(avg 1559 znaków): + +| batch | ms/chunk | +|------:|---------:| +| 32 | 22.70 | +| 64 | 16.57 | +| 128 | 15.82 | + +**Default batch 64 POTWIERDZONY** — zysk z 128 to ~4.5%, a przy 64 koszt bisekcji jest +mniejszy. Ekstrapolacja na 271k chunków: **~1.25 h GPU** vs ~11 h przy per-request. + +### Testy + +117 testów zielonych. + +## Wyjątki procesowe + +Żadnych. Commit z PIHA nie zaistniał — CC nie dopisał wskaźnika, uznano za zbędne. + +## TODO wynikające + +- **Rotacja hasła `kb-postgres`** — poszło do historii shella i na screeny sesji. +- **`POSTGRES_PASSWORD` plaintext w `services/*/service.yaml`** — kandydat na backlog + sekretów. +- **`kb-site` `robots.txt` blokuje fetch Claude** (`ROBOTS_DISALLOWED`) — fix: `X-Robots-Tag + noindex` zamiast `Disallow` (wariant B), przy okazji taska `kb-site`. +- **Backfill 271k** — dopiero po merge + deploy `task/prune-fix` (subsystem A).