spb/ka-guardian
Public
Python 57.1%
Shell 13.8%
CSS 12%
JavaScript 10%
HTML 7.2%
1# KA Guardian — ka2 · ka4 · ka6 (agents gardiens des connecteurs ET des sites)23Un seul repo pour les **3 sites gardiens** : www.ka2.bot, www.ka4.bot, www.ka6.bot.4Chaque agent est une instance de `orchestrator/main.py` (env `AGENT=ka2|ka4|ka6`),5identité (accent, tagline, services surveillés) dans `topology.json`.67## Où sont les apps ? → le registre mld, jamais en dur (2026-09-04)89L'**emplacement** de chaque service (nœud, IP LAN, répertoire, port web, process PM2)10vient du **registre de la passerelle** `M1M32:~/dispatch/registry.json`, appliqué par11`orchestrator/registry.py` au démarrage et à chaque tick (`registry.refresh` mute12`SERVICES`/`NODES` en place ; les déménagements sont journalisés dans le flux et dans13`/api/state → registry.changes`). `topology.json` ne porte que la correspondance14`service → registry_app` (+ `pm2_exclude` optionnel) ; ses champs `node/dir/web_port/pm2`15sont un **repli** si le registre n'a jamais été reçu — ne pas les « corriger » à la main,16c'est `mld` qui fait foi.1718- Copie locale : `~/ka-guardian-spool/registry.json` — **poussée** par `mld` (abonné `ka2`,19 `mld subscribers` sur M1M32) et **tirée** toutes les 2 min par le service launchd20 `com.ka.registry-sync` (`deploy/registry-sync.sh`, zsh pur : LNP interdit le LAN à python).21- Le même service sonde `:7791/health` de chaque nœud hébergeur → `~/ka-guardian-spool/runners.json`.22 Un nœud **sans runner** (app déménagée sur un nœud jamais équipé) est affiché « ⚠ sans runner »23 dans le territoire surveillé et l'orchestrateur **refuse d'y dépêcher** (log d'erreur 1×/h) :24 lancer `deploy/deploy.sh runners` (la liste des nœuds est elle-même dérivée du registre).25- Les process PM2 = `processes` du registre moins les tunnels `*-ngrok` moins `pm2_exclude`.26- Rollback après un déménagement : vise le nœud **actuel** du service (le repo git suit l'app).2728## Veilleur de sites (2026-08-25)2930En plus des connecteurs (scan api-ka), chaque agent surveille le **site public**31de chacun de ses services (`site_engine` dans main.py, source d'incident `_site`) :32331. GET du `site` de chaque service aux `site_check_interval_seconds` (120 s) ; down = ≥500/timeout, confirmé par un 2ᵉ essai puis `site_check_fails` (2) cycles consécutifs.342. Down confirmé → **pm2 restart automatique** via l'endpoint `/restart` du runner du nœud (throttle `site_restart_throttle_seconds`), re-check du site.353. Toujours down → incident `site_down` (priorité max au dispatch) → **mission Claude d'investigation** (`build_site_down_prompt`) sur le nœud : logs pm2, cause racine (crash, port, build, DB, disque, tunnel ngrok), correctif minimal, commit+push.364. Cycle standard ensuite : watching (fenêtre courte `site_watch_window_hours`), rollback si faux « repare », cooldown `site_cooldown_hours`, max 3 tentatives puis abandon (re-examen après `site_abandoned_retry_hours`). Les restarts automatiques continuent pendant les cooldowns.3738`vraiprix` (M3U96a, port 8090) est un service **site seulement** de ka6 : aucun39connecteur sous api-ka, seule la surveillance du site s'applique.4041## Production (nœud M4M36)4243- Répertoire : `~/cluster-projects/ka-guardian` (ce repo, origin = gitsrv/spbgit `ka-guardian.git`).44- Process : **launchd** (PAS pm2) — `com.ka2.guardian` (:8799), `com.ka4.guardian` (:8899), `com.ka6.guardian` (:8999). Tunnels ngrok `com.kaX.ngrok` (ne pas toucher).45- Pas d'étape de build : Python servi en place (`.venv` local au nœud).4647## Après toute modification (sur M4M36)48491. Redémarrer le ou les agents concernés :50 `launchctl kickstart -k gui/$(id -u)/com.ka2.guardian` (idem ka4/ka6 — les 3 partagent le code, redémarre les 3 si le changement est commun).512. Vérifier : `curl -sf localhost:8799/health` (8899, 8999) puis le site public.523. `git add … && git commit && git push origin main` (origin = gitsrv/spbgit, PAS GitHub).5354⚠️ NE JAMAIS redémarrer les **runners** (`com.ka.guardian-runner` sur chaque nœud hébergeur — liste vivante : `deploy/deploy.sh nodes`, dérivée du registre mld) pendant qu'ils sont occupés : ça tue la mission Claude en vol. Pour redéployer `runner/runner.py`, vérifier d'abord `curl localhost:7791/health` (`busy:false`) sur chaque nœud, comme le fait `deploy/deploy.sh runners`.55⚠️ Le trafic LAN direct est bloqué par macOS 26 (Local Network Privacy) — le courrier zsh `com.ka.guardian-courier` s'en occupe ; ne pas le contourner.5657## Pages & image de marque5859- `orchestrator/web/index.html` + `commander.html` : les jetons `__NUM__`, `__DOMAIN__`, `__TAGLINE__` (balises OG) sont rendus par agent au démarrage dans `main.py` (`_render_page`).60- Bannières de partage `orchestrator/web/og-ka{2,4,6}.png` (servies à `/og.png`) : régénérer sur le laptop avec `python3 deploy/make_og_images.py` (Playwright/Chromium) si l'identité visuelle change.6162## Déploiement complet depuis le laptop6364`deploy/deploy.sh orchestrators` (tar-over-ssh + vérif md5 + relance launchd). Source laptop : `~/Desktop/Groupe-KA/apps-web/ka-guardian`.65