# hermes-auto-improve — Analyse quotidienne de la documentation Hermes analyse chaque jour la base de connaissance `admin/`, écrit ses rapports dans `admin/hermes/builtin/` et pousse le tout sur la branche `hermes/daily-work`. Une PR squash-only vers `main` est créée (ou mise à jour) automatiquement. --- ## Architecture ``` n8n « Hermes Doc Worker » (22h00) │ POST http://192.168.10.1:9095/trigger/all ▼ trigger server (storage-01:9095, systemd hermes-auto-improve) │ lance en background thread ▼ /usr/local/bin/hermes-auto-improve --all │ pour chaque .md de admin/ (sauf hermes/builtin/) : │ prompt → Hermes (profil funk-ai, Qwen3-8B sur gpu-01) │ → rapport JSON (statut, score, problèmes, suggestions) ▼ admin/hermes/builtin/YYYY-MM-DD_HH-MM.md (rapport consolidé) │ git commit + push → hermes/daily-work ▼ n8n poll GET :9095/status (toutes les 5 min jusqu'à running=false) │ ▼ Email récap + PR GitHub (POST :9095/trigger/daily-pr) ``` ## Composants | Élément | Emplacement | Géré par | |---|---|---| | Script d'analyse | `/usr/local/bin/hermes-auto-improve` | rôle `hermes_auto_improve` (source `tools/hermes-auto-improve/auto-improve.py`) | | Trigger server | `/usr/local/bin/hermes-auto-improve-server` (`:9095`) | rôle `hermes_auto_improve` (source `tools/hermes-auto-improve/trigger-server.py`) | | Service systemd | `hermes-auto-improve.service` (le serveur HTTP, pas de timer) | rôle `hermes_auto_improve` | | Scheduling | workflow n8n `CX72UUOempE1YtNL` — Schedule 22h00 | n8n (voir `admin/k8s/n8n.md`) | | État de rotation | `/var/lib/hermes-auto-improve/state.json` | script | | Log des runs | `/var/log/hermes-auto-improve.log` | trigger server | | Clone de travail | `/srv/data/lab/Funk-lab` (branche `hermes/daily-work`) | script (git_sync au début de chaque run) | ## Modes du script ```bash hermes-auto-improve # batch de 5 fichiers (rotation via state.json) hermes-auto-improve --all # tous les docs en une passe (~60-90 min pour 28 fichiers) hermes-auto-improve --subdir ia # un sous-dossier admin/ uniquement hermes-auto-improve --dry-run # analyse sans écrire ni push hermes-auto-improve --daily-pr # crée la PR GitHub (ou met à jour celle ouverte) ``` ## Endpoints du trigger server (`:9095`) | Endpoint | Action | |---|---| | `POST /trigger` | run standard (batch de 5) | | `POST /trigger/all` | run complet `--all` | | `POST /trigger/subdir` | body `{"subdir": "ia"}` | | `POST /trigger/dry-run` | analyse sans commit | | `POST /trigger/daily-pr` | crée/met à jour la PR | | `GET /status` | `{running, last_result, state}` | | `GET /health` | healthcheck | Un seul run à la fois (`already_running` sinon). Timeout interne : 7200 s. ## PR GitHub - Branche : `hermes/daily-work` → `main`, **squash merge uniquement** (forcé côté repo GitHub) - S'il existe déjà une PR ouverte pour la branche, le script **met à jour** titre + corps au lieu d'en créer une nouvelle - Identité des commits : `Hermes Bot ` - Le push utilise les credentials `gh` de root sur storage-01 (`HOME=/root` dans le service) ## Vérifications rapides ```bash # Le serveur tourne ? curl -s http://192.168.10.1:9095/health # Un run est en cours ? Dernier résultat ? curl -s http://192.168.10.1:9095/status | python3 -m json.tool # Suivre un run en direct (le log n'est écrit qu'en fin de run — vérifier le process) ssh storage-01 'ps aux | grep "hermes-auto-improve --" | grep -v grep' ssh storage-01 'sudo tail -50 /var/log/hermes-auto-improve.log' ``` ## Pièges connus - **Le log n'est flushé qu'à la fin du run** — un run `--all` peut sembler silencieux pendant une heure. Vérifier le process ou compter les `POST /v1/chat/completions` dans `journalctl -u litellm`. - **`git pull --rebase` dans git_sync** : si on réécrit l'historique de `hermes/daily-work` (force push), il faut aussi reset le clone `/srv/data/lab/Funk-lab` sur storage-01, sinon le prochain run réincorpore les anciens commits. - **rag-ingest en fin de run** : échoue tant que Qdrant est HS (incident 2026-06-05) — le run reste valide, seule la ré-indexation est sautée. - Les rapports `admin/hermes/builtin/` sont indexés dans le RAG par `rag-ingest` (qui parcourt tout `admin/`) — pollution potentielle des résultats `rag-query`, exclusion à prévoir.