diff --git a/docs/architecture/PLAN-subsystem-a-2026-07-28.md b/docs/architecture/PLAN-subsystem-a-2026-07-28.md new file mode 100644 index 0000000..7f17f65 --- /dev/null +++ b/docs/architecture/PLAN-subsystem-a-2026-07-28.md @@ -0,0 +1,60 @@ +# Plan naprawy subsystemu A (control-plane) — 2026-07-28 + +Kontekst: docs/architecture/RECON-multiagent-2026-07-27.md. Decyzje bazowe: +- Flota dzieli się na dwa subsystemy. A = utrzymaniowy (control-plane, node-agenty, + self-healing) — ten plan. B = zleceniowy (dyspozytor + Telegram + KB + HA + + homelab-ops) — prowadzony w osobnym projekcie, poza tym planem. +- ai-cluster to legacy (bus martwy od 2026-06-09): wygaszany, NIE migrowany. + Branch task/ai-cluster-solaria zostaje niezmergowany jako dokumentacja reconu. +- SOLARIA jest desktopem (duty cycle ~16 h/d offline). Wszystko wymagane 24/7 + mieszka na PIHA. +- CHELSTY-INFRA: fizycznie martwa, będzie reanimowana. Do tego czasu dormant. +- Approvale ZOSTAJĄ (brak gotowości na full auto). Kryterium sukcesu etapu 2: + incydent -> powiadomienie Telegram -> approve -> serwis wstaje, end-to-end. +- webui (agents.okit.pl) + materializer zostają — rola: podgląd stanu. + Telegram — rola: powiadomienia + approvale. + +## Etap 0 — porządki w prawdzie (repo-only) +- CHELSTY-INFRA -> status dormant w topologii; supervisor pomija; skasować + pending redeploy ha-diag-agent. +- LUSTRO wpisać do topology.yaml (biega i raportuje, formalnie nie istnieje). +- Uzgodnić topology.yaml z hosts/*/services.yaml wg zasady: hosts autorytatywne. +- Dopisać do hosts/solaria/services.yaml to, co realnie biega (planner-agent, + stability-agent, node_exporter); los planner-agenta do decyzji przy okazji. +- Skasować martwe: scripts/deploy/deploy-role.sh, stała SERVICE_NAMES w + service_ops_worker.py, gałąź mqtt_unreachable w supervisorze. +- Adnotacja w repo: ai-cluster = legacy, wygaszany. + +## Etap 1 — przywrócenie zmysłów i rąk +1. SOLARIA: override group_add na host docker gid (996) w hosts/solaria — + odblokowuje raportowanie kontenerów i wykonywanie restartów. +2. stability-agent: emitować nazwę serwisu z labela compose zamiast service=None + (wzorzec z majowego fixu node-agenta). Potem decyzja: fuzja czujników w + node-agenta i wygaszenie stability-agenta (do potwierdzenia po przeglądzie + unikalnych funkcji stability-agenta). +3. Mapowanie supervisora: healthcheck_failed -> container_restart (redeploy wraca + do mapy dopiero gdy działa). + +## Etap 2 — pętla z człowiekiem +4. Naprawa redeploy: executor woła deploy przez ssh z VPS per-service; + deploy-node.sh musi honorować argumenty . +5. TTL na pending: 24 h -> expired, ID zwolnione, incydent może znów alarmować. +6. Telegram jako kanał approvali (approve/reject przy powiadomieniu). Nośnik: + telegram-bot z agent-systemu — w ramach tego kroku wciągnąć go do manifestów + (pierwszy element wciągania shadow setu). +7. Test końcowy etapu: kontrolowane ubicie serwisu (kandydat: gokapi, i tak + leży) -> alert Telegram -> approve -> serwis wstaje. + +## Etap 3 — retencja i zakres +8. Pruning eventów: retencja per typ (health ~3 d, incydentowe ~30 d, + action_result bezterminowo), format docelowy per-event JSON, cron na VPS. +9. Deklaracja zakresu monitoringu: każdy kontener na monitorowanych nodach albo + w manifeście, albo jawnie unmanaged: true z powodem. + +## Poza planem +- Wygaszenie kontenerów ai-clustra na VPS: osobna sesja (stop stacka, obserwacja + free -m, rollback = start). +- Subsystem B: osobny projekt. + +Zależności: 2 wymaga 1; 7 wymaga 4-6. Kolejność etapów wiążąca, kolejność wewnątrz +etapów — nie.