Commit graph

356 commits

Author SHA1 Message Date
oskar ca66d31f0a feat(documents-ingest): Paperless -> envelope adapter (module 5 phase 2 step 5)
Adds documents-ingest-paperless: paginated GET /api/documents/, maps each
doc to a source='paperless' envelope per plan §4.2-4.3, reusing
kb_mail.Envelope/insert_envelope unchanged (packages/kb-mail not touched).
Cross-source link (source_mail entity) is a deterministic join of
original_file_name against the phase-1 registry.json consume_name index —
no heuristics, no correspondent guessing (plan decision 4). Stats always
balance (fetched = already_in_db + inserted + errors) and main() now also
exits non-zero on imbalance, not just on errors>0, matching the exit-code
convention already established in gmail-bulk-import.

Verified live on PIHA (rsync to /tmp, ~/kb/venv, PIHA checkout untouched):
dry-run then --apply inserted 186/186 paperless envelopes (0 errors,
180 source_mail links), a second --apply reported inserted=0/already_in_db=186
(idempotent), gmail rows stayed at 225030 and document_chunk stayed empty.
Rotated the kb-ingest Paperless API token after it was accidentally
partially echoed during recon (old token now dead).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 15:24:25 +02:00
oskar 8fec62d509 docs(infra): shadow-run etap 2 — analiza 165 mismatchy solaria/lustro
Wszystkie mismatche = detection-lag przy planowych power-offach (prom szybszy
o ~9.5 min od TTL eventowego); zero fałszywych prom=down. vps/piha 100% zgodne.
Rekomendacja: GO dla etapu 3 per-node, mapping timestamp(up)->compute_liveness.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 14:54:27 +02:00
oskar 3755d7d6bb fix(gmail-bulk-import): harden re-import against 8-bit headers + poison batches
Four audit findings (2026-07-14), each reproduced on crafted mboxes; the
Takeout corpus has proven 8-bit header bytes, so all are real re-import risks.

1. Whole-run crash on 8-bit Message-ID. compat32 .get() returns an
   email.header.Header (not str) for raw 8-bit bytes; the old
   Header.strip() raised AttributeError. _message_id ran BEFORE the
   per-message try, so one bad header killed the entire import.
   Fix: str() + sanitize_surrogates() before strip; and move
   _message_id/_parse_date/_parse_attachments INSIDE the per-message try —
   a broken message is now errors += 1, never run death.

2. Poison batch. pending.clear() ran only AFTER a successful insert, so a
   failed flush (DB down / bad row) left pending intact and every later
   message re-flushed the doomed batch; the final flush sat in try/finally
   with no except and propagated out, losing all stats. Fix: _flush always
   clears pending and counts a failed insert as db_insert_failed; the run
   always reaches import_complete.

3. Stats didn't reconcile with the DB. imported counts archive writes, not
   DB rows, so a partial-insert drift was invisible. Fix: separate
   db_inserted/db_insert_failed counters; main() exits non-zero on any
   error, DB drift, or a processed = imported + skipped + errors imbalance.

4. 8-bit Date → needless epoch_fallback. parsedate_to_datetime(Header)
   raised even when str(header) parses fine. Fix: str() before the epoch
   fallback.

Shared helper: _sanitize moved from gmail-header-backfill into
packages/kb-mail (kb_mail.text.sanitize_surrogates) and used by both jobs;
gmail-header-backfill now depends on kb-mail.

Tests: regression coverage for all four findings in gmail-bulk-import
(8-bit id/date, per-message guard, failed-insert non-poisoning, stats
balance) plus kb_mail.text unit tests. Full suites green:
kb-mail 27, gmail-bulk-import 33, gmail-header-backfill 43.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 14:28:09 +02:00
oskar 4746ebe0fb fix(node-agent): detect restarting/crash-looping containers — state fell through classification, crash-loops were invisible to monitoring
check_containers() classified only exited/dead, running+unhealthy and running.
Docker's "restarting", "paused", "removing" and any future state matched no
branch, so a crash-looping container (restart policy + continuous crash) emitted
ZERO events and world-state kept showing it "healthy" (observed live:
lustro/pi-watchtower-1). Every Docker state is now handled:

- restarting + RestartCount >= CRASH_LOOP_RESTART_THRESHOLD (default 3):
  reuse containers_not_running (high, crash_loop=true) — parity with exited/dead,
  rides the existing supervisor-wired remediation path.
- restarting below threshold: new observational container_restarting (low),
  visible but non-actionable so benign post-deploy restarts don't alarm.
- paused / unknown-or-future state: new diagnostic container_state_unexpected
  (medium) — no more silent fall-through; new Docker states become visible.
- removing: conscious documented skip (ephemeral teardown).
- created: unchanged skip (compose tracking artifact).

RestartCount (top-level inspect field) distinguishes a crash-loop from a one-off
restart. Adds services/node-agent/tests/test_check_containers.py pinning the full
state table.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 20:11:56 +02:00
oskar f14ad410a0 fix(gmail-header-backfill): compat32 fallback + missing_file stat — 8-bit Date header crashed json.dumps mid-slice, losing 4999 rows
Diagnosis of the 5008 header-less envelopes after the full 225 030-row run
(read-only, on PIHA, 2026-07-14):

- 4999 = one contiguous block at ORDER BY id positions 70001-74999: the
  --offset 70000 slice died mid-run. Root cause reproduced: a Date: header
  with raw 8-bit bytes makes compat32 .get() return email.header.Header
  (not str), and json.dumps([headers]) — which sat OUTSIDE the per-row
  try/except — raised TypeError and killed the process, silently losing
  the rest of the slice.
- 9 = genuine typed-parse failures: 7x RFC 2047 encoded-word decoding to
  CR/LF inside a display name (ValueError in headerregistry), 1x RFC 5322
  group syntax in To: ("unlisted-recipients:;"), 1x CPython
  _header_value_parser bug on a malformed display name (fixed upstream,
  present on PIHA's 3.11).
- 0 missing .eml files.

Fixes:

- date_raw: str() + surrogate sanitization on the compat32 value — the
  crash cause, now also covered by a regression test.
- json.dumps moved inside the per-row try: a non-serializable value counts
  as that row's parse_error instead of crashing the slice.
- parse_headers_fallback(): on typed-parse failure retry with a pure
  compat32 parse — getaddresses over raw header text, raw-string values,
  same §4.1 entity shape. Counted separately as parsed_fallback (labeled
  subset of updated), logged per row with the original typed error.
- missing_file counter + skip.missing_file info log (id, expected path);
  run_complete now balances: scanned = updated + already_has_headers +
  parse_errors + read_errors + missing_file. Non-zero missing_file also
  fails the exit code.

Verified: 43/43 pytest locally (3.13) and on PIHA (3.11); read-only dry
runs on PIHA — all 9 parse failures recover via fallback, the lost slice
completes scanned=5000 updated=4999 already_has_headers=1 with zero errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 19:35:30 +02:00
oskar 31e30b04d1 docs(infra): monitoring coverage recon — co biega vs co monitorowane + plan domknięcia
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 19:25:51 +02:00
oskar d5139c99ca fix(observer): checkpoint by timestamp not lexical path — lexically-smaller-but-newer events were silently skipped forever (poisoned node)
Per-node checkpoint now stores the last-processed event TIMESTAMP (int epoch)
instead of a file path compared lexically. A file is "new" iff its timestamp
(parsed from evt-<node>-<unixts>-<type>-<svc>.json, mtime fallback) exceeds the
node's checkpoint; processing is ordered by timestamp, not path.

Root cause (PIHA dead ~34d, 2026-07-12): a stray evt-unknown-<ts>-… file landed
in events/piha/, lexically greater than every evt-piha-… name. The lexical
checkpoint pinned there, so every genuinely newer piha event sorted "before" it
and was skipped forever. Event backlog grew to 7344 files, last_seen frozen,
shadow-read logged false SHADOW_LIVENESS_MISMATCH event=dead prom=up.

- _event_ts_from_path: filename epoch, mtime fallback; NEVER returns 0 for an
  existing file (0 == "older than checkpoint" == the poison).
- _checkpoint_ts_from_value: graceful migration of pre-fix path-string
  checkpoints (and the older last_processed_file format) to int epochs;
  unparseable → 0 (reprocess all — safe, process_event is idempotent on
  last_seen/world_state; bias to reprocess, never to skip).
- Preserved: quarantine of bad events, observer-source re-ingest guard.
- Regression tests (test_incident_lifecycle.py section 9): lexically-smaller-
  but-newer processed, unparseable name falls back to mtime (not wedged),
  ts-not-path ordering, both checkpoint-format migrations, helper units.

Separate bug filed in backlog (not fixed here): ha-diag-agent emits node=
"unknown" events (config.py node_name default) into another node's dir when
NODE_NAME reaches the compose volume path but not the app env — the source of
the poison file.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:55:38 +02:00
oskar 80c33c487c feat(gmail-header-backfill): one-shot job — backfill headers into envelope.entities
Module 5 phase 2 (docs/kb/modules/05-faza2-plan.md, §5). 225,030 existing
source='gmail' envelope rows carry only an attachment manifest — no
from/to/cc/delivered_to/subject anywhere in the DB, which blocks answering
"is this on me or my wife" / distinguishing aliases (plan §1.8). Separate
job from gmail-bulk-import per plan §2 decision 7: UPDATE semantics against
production data is a different risk profile than the historical INSERT job.

Parses headers only (no MIME-walk of attachments) from the archived .eml
files, appends {"type": "headers", ...} (plan §4.1) via the idempotent
UPDATE ... WHERE NOT EXISTS from §5.2, batched via executemany. --limit/
--offset (ORDER BY id) give stable, deterministic partitioning so the full
backfill can run and be verified in slices instead of one unattended pass.

Plain CLI (pip install -e), no Dockerfile — same convention as
gmail-bulk-import/documents-ingest, which run directly on PIHA for local
filesystem access to the .eml archive.

Verified against kb-postgres@PIHA (100-row dry-run + apply, re-run proved
idempotent no-op, 1000-row timed slice): 1096/225030 rows backfilled,
996/1000 succeeded on the timed slice (4 parse_errors — a 2014 spam message
with an RFC 2047 encoded-word decoding to an embedded newline in the From
display name, correctly caught and skipped rather than crashing the batch).
Extrapolated full-run time ~16 minutes. Full 225,030-row run is out of
scope for this change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-14 15:34:07 +02:00
oskar cc5c7921e2 fix(node-agent): rsync --no-perms/--no-owner/--no-group — same aerbot-owned dir EPERM as dir-times (exit 23 after omit-dir-times fix) 2026-07-13 21:15:41 +02:00
oskar 8cafd9917f feat(kb-postgres): migration 002_chunks.sql — document_chunk table
Krok 1 planu docs/kb/modules/05-faza2-plan.md §3/§6 (chunk-level embeddings,
1:N do envelope). Addytywna — 001_envelope.sql nietknięta (zweryfikowane
\d envelope po migracji: identyczny schemat + FK jako "Referenced by").

Schemat wg rekomendacji recon (§2 decyzja 1+2): osobna tabela (nie kolumna
w envelope, bo N-wartościowy chunking jest obowiązkowy przy dokumentach
>8k tokenów), embedding VECTOR(1024) pod bge-m3 (dense), HNSW cosine index,
kolumna `model` do trywialnego re-indexu przy zmianie modelu (kb-00 zasada
#1: indeks odtwarzalny). Idempotentna (CREATE TABLE/INDEX IF NOT EXISTS,
zweryfikowane podwójnym uruchomieniem na kb-postgres@PIHA — drugi run same
NOTICE "already exists, skipping").

Zastosowana na żywej bazie: ssh piha docker exec kb-postgres psql, po
potwierdzeniu SQL przez Oskara. \dt + \d document_chunk + \d envelope
zweryfikowane po migracji.

Testy: dopisane sanity-testy 002 do packages/kb-mail/tests/test_migration.py
(wzorzec 001 — statyczne assercje na treści SQL, bez DB), 13/13 zielone.

Co NIE jest częścią tego kroku (§3 planu, odłożone): entity/entity_link
(graf encji) — szkic na przyszłość, nie blokuje domknięcia modułu 5.

Co dalej (plan §6, poza zakresem tego kroku): ollama pull bge-m3 na SOLARII,
token API Paperless, jobs/gmail-header-backfill/, adapter Paperless→koperta,
chunking+embed job.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-13 21:13:13 +02:00
oskar 8ae2c2481a docs(kb): plan fazy 2 modułu 5 — koperta dokumentów (recon + plan v2) 2026-07-13 21:11:30 +02:00
oskar f37f85f1bc fix(node-agent): rsync --omit-dir-times — dir mtime on VPS not settable (aerbot-owned), caused false "shipping failed" despite successful transfer
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-13 20:54:37 +02:00
oskar f7b61f7da9 feat(documents-ingest): PDF attachment extractor — mail archive -> Paperless consume/
Module 5 phase 1 (docs/kb/modules/05-documents-ingest.md): pulls a sample of
PDF attachments (>50KB, last year, LIMIT 150) out of the Gmail .eml archive
and drops them into Paperless consume/ for OCR, so the RAG layer has real
documents to work with before the full Paperless/Nextcloud envelope adapter
is built. sha256-first attachment matching (manifest filenames can carry raw
RFC 2047 encoded-word artifacts that don't byte-match what email.policy.default
decodes today — confirmed against live data, ~10% of candidates were affected).
Idempotent via a sha256-keyed JSON registry; dry-run by default, --apply to write.

Verified end-to-end on PIHA: dry-run + --apply both run against live
kb-postgres/archive, 185/222 candidate PDFs written to consume/ (37 in-run
duplicates correctly deduped), Paperless picked them up and started OCR
immediately.
2026-07-13 20:03:57 +02:00
oskar fe575fa524 fix(node-agent): PIHA — group_add gid 123 (docker) so agent can read /var/run/docker.sock (was PermissionError, agent blind to containers) 2026-07-13 20:02:20 +02:00
oskar f135365da5 docs(sesja): 2026-07-12 Deploy 2 OCR-worker DZIALA (split-host NFS) + backlog: nowe serwisy KB poza monitoringiem 2026-07-12 21:15:38 +02:00
oskar 196a99ffef fix(paperless-worker): celery command bypassed manage.py + missing shared scratch dir
Two config bugs found on the already-deployed split-host OCR worker
(module 3): (1) `command: celery ...` was routed through manage.py by
the image entrypoint because it didn't start with "/" — fixed with an
absolute gosu+celery path. (2) SCRATCH_DIR (/tmp/paperless) was not
shared over NFS like data/media/consume, so tasks picked up by
worker@SOLARIA instead of worker@PIHA failed with "File not found" —
fixed by adding a paperless_scratch NFS volume/bind mount on both
sides.

Verified live on PIHA + SOLARIA: test PDFs dropped into consume/ were
split across both workers, the SOLARIA-picked task completed OCR with
zero File not found errors, test documents cleaned up afterward.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 20:51:04 +02:00
oskar 52e412dba3 docs(backlog): bug checkpoint observera (leksykalne porównanie ścieżek zatruwa węzeł) + bug deploy-local.sh rozkłada control-plane na ghostach 2026-07-12 20:11:34 +02:00
oskar 84c1d40c9a docs(backlog): tech-debt — globalny porządek uid/gid/uprawnień floty (systemowy, historia incydentów + kierunek) 2026-07-10 23:11:38 +02:00
oskar 5a0e149031 fix(node-agent): PIHA agent uses dedicated /opt/homelab/agent-ssh (uid 1000) instead of oskar's .ssh (uid 1004) — fixes event shipping 2026-07-10 18:31:39 +02:00
oskar 07a0fe097b docs(sesja): 2026-07-10 Deploy 1 Paperless LIVE (OCR+OIDC dziala) + swap PIHA 8Gi + npm-API w akcji + lekcje 2026-07-10 18:29:10 +02:00
oskar 5daae77e2f feat(scripts): npm_api.py — CLI do zarzadzania npm PIHA+VPS przez REST API
token/list-hosts/list-certs/set-cert/create-host, dry-run domyslny dla
zmian (--apply wymagane), stdlib urllib (zero-dep). Adresy npm@VPS
przez Tailscale (100.95.58.48:81), NIE public IP.

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

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

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

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

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

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

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

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

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

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

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

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

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

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 19:29:24 +02:00