Find a file
oskar 52eca1c22a fix(dispatch): inbox 0o775 + rsync rc=23 przestaje byc cichy
Wyciek plikow dispatch potwierdzony 2026-08-06 (session log, follow-up #1):
LUSTRO re-pullowalo te same dwie akcje co 60 s przez wiele dni, odbijajac sie
od bramki idempotencji, i nie zostawilo po sobie ani jednej linii w logach.

Przyczyna zlozona z dwoch niezaleznych defektow:

1. Executor tworzyl actions/dispatch/<node>/ z 0o755 (aerbot:aerbot). Rsync-pull
   z noda uwierzytelnia sie jako inny uzytkownik, bedacy tylko *czlonkiem* tej
   grupy. --remove-source-files musi zrobic unlink pliku, a unlink wymaga prawa
   zapisu w katalogu nadrzednym, nie na samym pliku. Zrodlo przezywalo pobranie.
   (dispatch/piha mialo historycznie 775 i dlatego dzialalo.)

2. node-agent traktowal rc=23 jako benign obok 0 i 24, wiec rsync zglaszal
   porazke, a agent ja polykal.

Executor: _ensure_inbox_dir() = mkdir + bezwarunkowy os.chmod(0o775). chmod jest
bezwarunkowy z dwoch powodow: mkdir(mode=) jest maskowany przez umask procesu
(przy 0o022 daje dokladnie feralne 0o755), a inboxy zalozone przez wczesniejszy
build juz istnieja na flocie z 0o755. Naprawa w miejscu zapisu, a nie skanem przy
starcie: jedno idempotentne wywolanie na tej samej sciezce kodu, ktora pisze plik
dispatch, wiec nie da sie rozjechac z pisarzami. Blad chmod nie jest fatalny —
akcja i tak sie wykonuje, a nieskasowane zrodlo widac teraz po stronie noda.

Objete tez actions/deploy/<node>/ (deploy-runner): ten sam wzorzec drenowania
tym samym rsync-pullem, ten sam defekt, jedno wywolanie obok.

node-agent: klasyfikacja kodow wyjscia zamiast wspolnej listy benign.
Weryfikacja empiryczna rsync 3.4.1 pokazala, ze rc=23 pokrywa dwa rozne
przypadki, a rozroznia je dopiero stderr:
  * `change_dir ... No such file or directory` — executor zaklada inbox dopiero
    przy pierwszym dispatchu, wiec kazdy nod, do ktorego nic nie poszlo, dostaje
    rc=23 co cykl. DEBUG — inaczej byloby po linii na minute z wiekszosci floty
    i realny sygnal utonalby w szumie.
  * `sender failed to remove <plik>: Permission denied` — wlasnie ten wyciek.
    WARNING z pelnym stderr.
Pusty (ale istniejacy) inbox to rc=0, nie 23 — dotychczasowy komentarz w kodzie
mowil inaczej. rc=24 zostaje benign (wyscig z executorem piszacym inbox),
pozostale kody to teraz ERROR, nie WARNING. Zachowanie funkcjonalne bez zmian:
retry i idempotencja dzialaja jak dotad, zmienia sie wylacznie widocznosc.

Testy: 4 nowe w test_executor_dispatch.py (oba inboxy 0o775 pod umask 0o022,
naprawa istniejacego 0o755 in place, dispatch przezywa nieudany chmod), 5 w
test_action_dispatch.py na klasyfikacje rc. Zastapiony
test_pull_treats_empty_source_returncodes_as_non_error — kodyfikowal wlasnie to
zalozenie, ktore okazalo sie bugiem. Oba zestawy sprawdzone mutacja: bez chmod
padaja 3 testy executora, przy starej liscie benign pada test rc=23.

node-agent 70 passed, control-plane 173 passed.

Refs docs/sessions/2026-08-06.md (follow-up #1)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 13:42:47 +02:00
.claude/skills fix(kb): przepiecie wszystkich odwolan wewnetrznych po migracji 2026-08-04 16:58:46 +02:00
backups/zigbee Add Zigbee coordinator backup 2026-05-14 18:24:26 +02:00
docs/sessions docs: session 2026-08-06 — weryfikacja safe-cleanup na LUSTRO + pierwszy cykl HITL 2026-08-06 13:16:26 +02:00
dotfiles add shared zshrc 2026-05-10 20:52:44 +02:00
hardware/esp/ir-ac-ha-integration feat(kb): przenosiny type=service do kb/services/ (13 plikow, bez SPLIT) 2026-08-04 16:58:04 +02:00
hosts docs(kb-site): przepisz nieaktualne kb.okit.pl na kb-e2a24af3.okit.pl 2026-08-05 13:08:13 +02:00
inventory feat(supervisor): duty-cycle nodes — liveness transitions logged, not actioned 2026-08-05 13:48:29 +02:00
jobs eval(retrieval): przekwalifikuj N2 na mail_query M5, nowa kontrolka N3 2026-08-06 13:22:23 +02:00
kb feat(kb-query): domyslny mode /search = hybrid (DoD (d) fazy mailowej) 2026-08-06 13:30:06 +02:00
packages fix(mail-body-ingest): usuwaj NUL (0x00) z tekstu przed chunkowaniem i embedem 2026-08-06 11:14:09 +02:00
scripts fix(kb-site): token bramki w kazdym linku wewnetrznym generatora 2026-08-05 20:29:27 +02:00
services fix(dispatch): inbox 0o775 + rsync rc=23 przestaje byc cichy 2026-08-06 13:42:47 +02:00
.codex Document current homelab state 2026-04-15 17:37:25 +02:00
.gitignore feat(kb): generator publicznej warstwy KB (gen_pages.py) 2026-08-04 17:57:15 +02:00
.mcp.json feat(ha-mcp): read-only MCP server (faza 2a) 2026-07-30 16:47:27 +02:00
CLAUDE.md fix(kb): przepiecie wszystkich odwolan wewnetrznych po migracji 2026-08-04 16:58:46 +02:00
codex_context Add session context state 2026-04-20 22:10:39 +02:00
codex_context.yaml add shared context lock 2026-05-05 17:25:50 +02:00
deploy_agent.py Add deploy escalation output 2026-04-22 22:08:26 +02:00
ollama_client.py Initial shared homelab agent workspace 2026-05-03 19:37:40 +02:00
README.md fix(kb): przepiecie wszystkich odwolan wewnetrznych po migracji 2026-08-04 16:58:46 +02:00
start-aider.sh Initial shared homelab agent workspace 2026-05-03 19:37:40 +02:00
start-codex.sh Initial shared homelab agent workspace 2026-05-03 19:37:40 +02:00
sync-context.sh add shared context lock 2026-05-05 17:25:50 +02:00
update-context.md Initial shared homelab agent workspace 2026-05-03 19:37:40 +02:00

Homelab Codex

GitOps-lite orchestration for a distributed homelab environment.

Architecture

The homelab consists of several nodes connected via a Tailscale internal mesh.

Host Role Description
SATURN Primary Node Development, orchestration, and git source of truth (commit node).
SOLARIA Compute Node GPU, inference, and heavy compute workloads.
PIHA Infra Node Core infrastructure services, automation, and monitoring.
VPS Edge Node Public ingress, reverse proxy, and edge services.

Agent System

The homelab uses a multi-agent orchestration model with human-in-the-loop for destructive actions:

Agent Node Role
stability-agent all nodes Per-node watchdog — monitors Docker, disk, Tailscale, MQTT; emits events
node-agent all nodes Publishes container health events to Redis pub/sub
observer VPS Synthesizes world state from events into /opt/homelab/world/*.json
supervisor VPS Detects drift between desired and actual state; writes pending actions
planner-agent SOLARIA LLM-powered diagnosis — listens to Redis, proposes remediation actions
executor VPS Executes actions only after operator approval
operator-ui + telegram-bot VPS / PIHA Operator reviews and approves/rejects pending actions

Action approval flow: pending/ → operator approves → approved/ → executor runs.

Repository Structure

Getting Started

  1. Standardization: Follow the Infrastructure Standards.
  2. Deployment: See Deployment Conventions for how to roll out changes.
  3. SATURN: Remember that SATURN is the only node where commits should be made.

Documentation Index


Note: This repository documents the state of the homelab. Runtime state lives outside the repository in /opt/homelab.