Pipeline complet dans feature/hermes-auto-improve :
- auto-improve.py : analyse admin/ avec hermes --profile funk-ai, applique
les améliorations, committe dans la branche, ré-ingère dans Qdrant
- trigger-server.py : HTTP 9095 (POST /trigger, /trigger/all, /trigger/subdir,
/trigger/dry-run) pour déclenchement depuis n8n ou manuellement
- Ansible role hermes_auto_improve : déploie scripts + service systemd sur s01
- n8n workflow "Hermes Auto-Improve" (ID: CX72UUOempE1YtNL) : schedule
hebdo dimanche 09h + webhook manuel → analyse → résumé LLM → email
Tout reste dans cette branche — rien ne touche main avant review.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Réécriture complète pour une expérience chat naturelle :
- Mode VEILLE : écoute "Ok Hermès" → active la conversation
- Mode CONVERSATION : 60s de parole libre sans répéter le wake word
- webrtcvad mode=3 (remplace détection énergie) — fini les faux déclenchements
- Single large-v3 (supprime la détection 2 niveaux peu fiable)
- VOICE_INJECT prefix pour forcer des réponses courtes
- Mots de sortie : "au revoir", "bonne nuit", "stop hermes", "fin"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- VAD mode : Whisper small (~0.3s) pour détecter "ok hermes", large-v3 uniquement pour transcrire la commande
- PTT mode : large-v3 direct (inchangé)
- install-service.sh : installe hermes-voice comme service utilisateur systemd (auto-start à la session)
- doc mise à jour
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- tools/hermes-voice/ : pipeline VAD → faster-whisper → LiteLLM → piper TTS
- mot-clé "hermes" détecté dans la transcription Whisper (pas de wake word model)
- modes : VAD continu + push-to-talk + --no-tts pour debug
- nftables : ouvrir port 4000 LiteLLM vers LAN domestique (192.168.1.0/24)
- admin/ia/hermes-voice.md : documentation installation et utilisation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Installation poste perso + storage-01, configuration namespace par défaut,
raccourcis navigation, cas d'usage fréquents, dépannage.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
n8n tourne dans un pod k8s — le port 25 de postfix n'était ouvert
que pour 192.168.10.0/24 (nœuds cluster), pas pour 10.42.0.0/16
(pods). Connexion ETIMEDOUT au nœud Send Email du workflow alertes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Brevo rejetait les mails envoyés depuis aliyesilkaya93@gmail.com
(domaine non vérifié côté Brevo). Gmail SMTP signe lui-même les mails
→ livraison garantie vers le compte Gmail destinataire.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
LiteLLM écoutait sur 127.0.0.1 uniquement — les pods k8s (10.42.x.x)
ne pouvaient pas atteindre 192.168.10.1:4000, Open WebUI affichait
"Aucun modèle disponible". Binding changé en 0.0.0.0 + nftables ouvert
pour 192.168.10.0/24 et 10.42.0.0/16.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Grant user privileges : ajout no_log:true (mot de passe visible en clair
dans les logs Ansible en cas d'échec via item loop)
- Alias 'db' déprécié par community.postgresql → renommé 'database'
- litellm DB recrée manuellement (corruption pg_attribute copiée depuis RAID)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
La tâche "Mount RAID5 array (fstab + immediate)" écrasait l'entrée fstab
bind-mount (/home/data → /srv/data) et remontait le RAID à chaque apply.
- Suppression de ansible.posix.mount state=mounted pour le RAID
- La tâche mdadm.conf devient conditionnelle (when: stdout non vide)
et failed_when: false pour ne pas bloquer si le RAID n'est pas assemblé
- Ajout d'un sanity-check : vérifie que /srv/data est un répertoire
- Commentaires explicatifs dans tasks/ et defaults/ pour prévenir toute
régression future
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Open WebUI (openwebui.lab.local) :
- Connecté à LiteLLM (192.168.10.1:4000/v1) comme backend OpenAI-compatible
- PostgreSQL via storage-01 pour l'historique des conversations
- PVC 5Gi NFS pour les uploads, Traefik IngressRoute
n8n (n8n.lab.local) :
- PostgreSQL via storage-01, chiffrement des credentials
- PVC 2Gi NFS, Traefik IngressRoute
- Webhook URL interne : http://n8n.lab.local
Ansible : ajoute openwebui et n8n dans postgresql_databases/users
(vault_pg_openwebui_password + vault_pg_n8n_password à ajouter au vault)
Prérequis avant 1er déploiement :
make vault-edit # ajouter les 2 passwords
make apply-storage --tags postgresql
kubectl create secret generic open-webui-secret -n ai ...
kubectl create secret generic n8n-secret -n ai ...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Incident : sdb ATA bus errors sous charge I/O bloquaient le rsync en état D
- Résolution : sdb marqué (F) dans mdadm, rsync relancé (205 MB/s, 35s)
- Fix : version.info corrompu dans segment Qdrant RocksDB (0.D\0 → 0.6.0)
- Architecture : /srv/data bind-monté depuis /home/data (NVMe XFS, 801 GB libres)
- fstab mis à jour, tous les services opérationnels
- CLAUDE.md : venv bootstrap, make --tags invalide, incidents.md dans admin/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Indexation de admin/ (284 chunks) dans Qdrant via embeddings Qwen3-8B.
rag-query utilisable en CLI et depuis le profil funk-ai de Hermes.
Note: modèle d'embedding générique — qualité limitée, voir admin/ia/rag.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Les pods AlertManager (10.42.0.0/16) ne pouvaient pas joindre le webhook
sur storage-01:9093 — alertes Prometheus reçues mais jamais transmises à
ask-agent monitor. Port 9093 ajouté pour pods k8s + nœuds cluster.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
instance=~"192\.168\.10\.(11|12|13):9100" → job="node-exporter"
La barre oblique inversée dans les regex PromQL string literals causait
une erreur "unknown escape sequence" (\. n'est pas un escape PromQL valide).
job="node-exporter" est équivalent (seuls les 3 compute nodes ont ce job)
et ne dépend pas d'adresses IP hardcodées.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
nftables.conf.j2 :
- Ajoute 10.42.0.0/16 (CIDR pods k8s) pour port 9100 (node_exporter)
et port 8080 (hermes webhook AlertManager)
- Appliqué live sur storage-01 + persisté dans /etc/sysconfig/nftables.conf
- storage-01 était up=0 (timeout) car pods Prometheus ne pouvaient pas
l'atteindre malgré node_exporter actif
dashboard-infrastructure.yaml :
- Corrige mountpoint /srv → /srv/data (RAID5 monté sur /srv/data)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- check_k8s_pods : grep -c retournait "0\n0" (|| echo 0 inutile quand
grep-c affiche 0 même en cas d'absence de match) — utilise un cache
intermédiaire pods_output + running=$(grep -c) || running=0
- cmd_start : uncordon automatique si nœuds SchedulingDisabled détectés
(séquelle d'un funk-stop --k8s), suivi d'une attente pod infra avant
le check — évite de devoir passer --k8s juste pour débloquer le cluster
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>