- 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>
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>
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>
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>
Ajoute check_k8s_pods / check_k8s_workloads (argocd, infra, monitoring).
funk-start vérifie désormais les pods k8s si les nœuds sont joignables,
même sans --k8s. En mode --k8s : attente ArgoCD + infra avant le check.
funk-status montre aussi l'état des pods si cluster up.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
hermes-agent spawne des process Python qui survivent hors du cgroup
systemd après stop_service. Ils gardent des file descriptors ouverts sur
/srv/data (logs, state.db-shm) et bloquent le umount.
Ajout d'un lsof + kill -9 sur tous les process tenant /srv/data avant
sync + umount — garantit un démontage propre sans dépendre de systemd.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Avant, shutdown -h now était appelé directement après stop qdrant/postgresql.
systemd démontait /srv/data pendant la séquence d'extinction sans garantie
que tous les buffers aient été flushés.
Séquence ajoutée avant shutdown :
1. stop nfs-server (était oublié dans le script)
2. sync — flush tous les buffers disque
3. umount /srv/data — démontage explicite du RAID5
Si umount échoue, lsof affiche le processus bloquant avant d'abandonner.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Après funk-stop --k8s, les nœuds reviennent Ready mais SchedulingDisabled
(cordon stocké dans etcd). Sans uncordon, tous les pods restent Pending.
Ajouts dans funk-start --k8s :
- kubectl uncordon sur les nœuds SchedulingDisabled uniquement (idempotent)
- Attente ArgoCD Running (jusqu'à 3 min) — confirme que le GitOps est opérationnel
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remplace le talosctl shutdown immédiat par une séquence en 6 étapes :
1. kubectl cordon tous les nœuds (empêche rescheduling)
2. kubectl drain compute-02/03 (SIGTERM pods, 30s grace, PVCs NFS libérés)
3. kubectl drain compute-01 (ArgoCD, system pods)
4. Vérification NFS : ss confirme plus de sessions :2049 actives
5. talosctl shutdown (halt propre, plus rien ne tourne)
6. Attente extinction ping
Prometheus et Grafana ont 30s pour flusher WAL/SQLite avant terminaison.
storage-01 (NFS server) est éteint en dernier une fois la vérification passée.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ansible roles:
- node_exporter : déploie node_exporter v1.9.1 sur storage-01 et gpu-01
avec textfile collector + services systemd. ROCm activé sur gpu-01 uniquement
via group_vars. Collecte métriques GPU via sysfs (temp, VRAM, utilisation)
— pas de dépendance rocm-smi (remplacé dans ROCm 7.x)
- alertmanager_webhook : service Python sur storage-01 (:9093/webhook)
reçoit alertes AlertManager et les route vers ask-agent monitor → Hermes
Playbooks: node_exporter + alertmanager_webhook ajoutés à storage-01 et gpu-01
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- SOUL.md funk-ai : tableaux détaillés system vs monitor (quand appeler
chaque agent avec exemples concrets), section delegate_task vs ask-agent
- SOUL.md system : rôle clarifié (traitement texte, PAS analyse santé),
format de réponse explicite (verdict direct, pas de préambule)
- hermes-agent.service : SupplementaryGroups=systemd-journal pour que
journalctl fonctionne sans sudo depuis le Terminal de Hermes
- Ansible common : admin_user (alkatrazz) ajouté au groupe systemd-journal
- admin/hermes.md : section SOUL.md complète (déploiement, contenu, profils)
- admin/ask-agent.md : distinction system vs monitor documentée avec
tableau et exemples, note /no_think, monitor réservé supervision
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Nouveau rôle hermes_user : création user/group UID 1002 sur storage-01
et gpu-01, sudoers limités par host, clé SSH ed25519 générée sur
storage-01 et distribuée vers gpu-01, ssh_config + known_hosts
- Kubeconfig copié depuis ansible vers hermes sur storage-01
- ask-agent : script bash LiteLLM pour déléguer aux agents
system/monitor/brain/funk-ai
- hermes-skills/funk/agent-delegation : skill Hermes pour les
inter-profile calls avec pattern Terminal: ask-agent
- Playbooks storage-01 et gpu-01 : ajout du rôle hermes_user
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- incidents.md : incident corruption EXT4 après arrêt brutal (655 erreurs,
e2fsck, réinstall hermes-agent, nouveau chemin /opt/hermes/.hermes/)
- hermes.md : arborescence mise à jour (code SSD vs données RAID5),
chemins pip/venv/frontend corrigés
- Ansible role hermes_agent : venv path et wrapper mis à jour
(hermes_home/.hermes/hermes-agent/venv/ au lieu de hermes_data_dir/)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove admin/ from .gitignore (repo is now private)
- Add --tui flag to hermes-dashboard.service template
- Document hermes-tui wrapper, dashboard access, TUI usage
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>