nas-runbooks/common/PROTOCOL-INFRA.md

9.0 KiB

PROTOCOL-INFRA — Regles operationnelles infra

Protocole post-deployement (OBLIGATOIRE)

Apres tout deployement reussi ou probleme resolu, avant de cloturer la mission :

  1. Creer un runbook dans le repo Gitea bolbol/nas-runbooks

    • Ecrire UNIQUEMENT dans le dossier hermes-[identite]/
    • Utiliser le template /opt/data/RUNBOOK-TEMPLATE.md
    • La section "Ce qui NE fonctionne PAS" est OBLIGATOIRE
  2. Poster une note NyoraNotes

    • Tags : [infra, runbook]
    • Contenu : resume du probleme, solution, lien runbook Gitea
  3. Mettre a jour _INDEX.md dans nas-runbooks

    • Ajouter l entree dans le tableau de l instance
  4. git add . && git commit && git push vers Gitea

Regle de contribution

  • Ecriture : chaque instance ecrit UNIQUEMENT dans son dossier hermes-[nom]/
  • Lecture : tous les dossiers sont accessibles en lecture
  • Le runbook sans les echecs n a pas de valeur — toujours documenter les tentatives infructueuses

Acces Gitea nas-runbooks

URL clone : http://192.168.100.33:3232/bolbol/nas-runbooks.git Dossier local suggere : /opt/data/workspace/nas-runbooks/


REGISTRE DES SERVICES — Mise a jour obligatoire

Le fichier /volume1/docker/ports-registry.md est la source de verite de l'etat du NAS. Il contient deux sections distinctes a maintenir en permanence :

1. SERVICES ACTIFS (en tete du fichier)

Mise a jour OBLIGATOIRE a chaque installation OU desinstallation :

  • Installation : ajouter la ligne avec statut ACTIF, port, domaine, notes
  • Desinstallation : changer le statut en "DESINSTALLE JJ/MM/AAAA", liberer le port
  • Ne JAMAIS supprimer une ligne — les services desinstalles restent visibles avec leur date

2. Historique des modifications (fin du fichier)

Ajouter une ligne datee pour CHAQUE action :

  • Format : | AAAA-MM-JJ | ACTION | Port | Service |
  • Actions a documenter : Deploiement, DESINSTALLATION, Migration, Changement de port

Verification avant documentation

Avant de marquer un service comme DESINSTALLE, TOUJOURS verifier : curl --max-time 4 http://172.17.0.1: -o /dev/null -w "HTTP %{http_code}" Si le port repond → le service est encore actif → NE PAS marquer DESINSTALLE

Chemin du fichier

  • Copie locale NAS : /volume1/docker/ports-registry.md
  • Copie nas-runbooks : /volume1/docker/nas-runbooks/common/ports-registry.md
  • Les deux doivent rester synchronisees (copier l'un vers l'autre apres modification)
  • Push Gitea obligatoire apres toute modification

Skills transverses — deploiement automatique sur les 3 instances

Quand une lecon apprise doit etre appliquee automatiquement par l agent (pas juste documentee pour lecture humaine), la deployer comme skill actif plutot que de compter sur un rappel manuel a chaque fois :

  1. Creer data/skills//SKILL.md sur les 3 instances (hermes-tt, hermes-nyora, hermes-perso), avec un frontmatter description contenant les mots-cles qui doivent declencher le skill
  2. Supprimer le cache .skills_prompt_snapshot.json (racine data/ et data/.hermes/) sur les 3 instances pour forcer la regeneration de l index
  3. Redemarrer les 3 containers hermes-agent-* (via socket Docker /var/run/docker.sock depuis mcp-nas, ou Portainer)
  4. Documenter quand meme via le protocole standard (runbook common/, _INDEX.md, note NyoraNotes) — le skill rend la regle automatique, le runbook garde la tracabilite

Exemples deployes le 02/07/2026 : desactivation des skills concurrents a nyora-doc-api (docx/pdf/pptx/xlsx), et skill generation-contenu-volumineux (chunking obligatoire pour eviter la troncature DeepSeek V4 Flash sur les taches lourdes).


Verification obligatoire avant toute lecture/ecriture sur nas-runbooks depuis mcp-nas

Git est ABSENT du container mcp-nas (confirme le 02/07/2026). Toute ecriture sur bolbol/nas-runbooks depuis une session mcp-nas passe par l API Gitea (curl + token, PUT/POST /api/v1/repos/bolbol/nas-runbooks/contents/, avec le sha courant recupere par un GET prealable) — jamais par un dossier local suppose a jour.

Piege decouvert le 02/07/2026 : /mnt/docker/nas-runbooks etait un clone git reel mais sur branche locale master, alors que le remote n a qu une branche main. 14 commits locaux (15-23 juin, jamais pousses) contenaient du contenu reel absent du remote. Cause probable : le binaire git a disparu de mcp-nas avant l etape push. Fix applique : recuperation des 14 fichiers via l API vers main, _INDEX.md corrige, clone local renomme en nas-runbooks.STALE-clone-local-jamais-pousse-20260702 (conserve pour inspection, plus utilise comme source).

Regle : avant de lire ou modifier un fichier sous /mnt/docker/nas-runbooks (ou tout repo Gitea) depuis mcp-nas, verifier d abord via l API que le contenu local correspond au remote reel : GET /api/v1/repos/bolbol//branches GET /api/v1/repos/bolbol//contents/ Si un vrai clone git fonctionnel est necessaire (multi-fichiers, historique), le faire depuis le Mac ou git est present, chemin partage /Volumes/docker == /volume1/docker.

gstack (garrytan/gstack) — decision actee le 02/07/2026

Installation prevue sur le futur MacBook M5 Pro via Claude Code natif, PAS sur hermes-perso (mem_limit container 600m incompatible Chromium/Playwright, routing Sonnet/Opus incompatible regle DeepSeek exclusif Hermes, bug upstream #2015 AskUserQuestion/clarify non resolu sur --host hermes). Detail complet : common/GSTACK-EVALUATION-MACBOOK-VS-HERMES.md.

Piege .env vs docker-compose.yml — decouvert le 03/07/2026

Ajouter une variable au .env d un service NE SUFFIT PAS si le docker-compose.yml declare un bloc environment: qui whiteliste explicitement chaque variable transmise au container (cas d hermes-platform/docker-compose.yml). Une variable absente de ce bloc n atteint jamais le container meme si elle est correcte dans le .env.

Regle : pour toute nouvelle variable d integration (cle API, URL de service), toujours verifier ET modifier les deux fichiers :

  1. .env (definition de la valeur)
  2. docker-compose.yml, bloc environment: du/des service(s) concerne(s) (transmission de la valeur au container)

Verification post-fix : docker exec env | grep sur le container recree.

Cas reel : NYORA_DOC_API_KEY manquante des deux fichiers pour les 3 instances Hermes -> 401 sur nyora-doc-api. Detail complet : common/nyora-doc-api-hermes-guide.md, section "Panne corrigee le 03/07/2026".

RÈGLE CRITIQUE — Cron Hermes et publish n8n : une modif écrite sur disque n'est pas une modif live

Cron Hermes (jobs.json)

Le service cron de chaque agent Hermes (hermes-agent-tt / hermes-agent-nyora / hermes-agent-perso) charge jobs.json UNIQUEMENT au démarrage du container. Il ne relit jamais le fichier en cours de route. Modifier jobs.json (horaire, prompt, modèle) laisse le service tourner avec l'ancienne config en mémoire tant que le container n'est pas redémarré.

  • Après toute modification de jobs.json : redémarrer le container agent correspondant (nom réel : hermes-agent-tt / hermes-agent-nyora / hermes-agent-perso — PAS hermes-tt/hermes-nyora/hermes-perso, ce sont les containers hermes-workspace-*).
  • Restart via API Portainer : POST /api/endpoints/2/docker/containers/{id}/restart timeout systématiquement sur cette instance. Utiliser stop puis start explicites (2 appels), pas restart.
  • Après redémarrage, TOUJOURS vérifier next_run_at dans jobs.json correspond bien au nouveau schedule — sinon le corriger manuellement (le daemon ne recalcule pas toujours correctement au premier boot).
  • Portainer : endpoint local = id 2. Auth via 172.17.0.1:9000/api/auth (pas 192.168.100.33 depuis un container), credentials dans hermes-platform/.env.

Publish n8n (workflow actif modifié via l'outil update_workflow)

update_workflow sauvegarde un brouillon (nouveau versionId) mais n'active PAS automatiquement ce brouillon sur un workflow déjà publié — le workflow continue de servir l'ancienne activeVersion. publish_workflow peut échouer silencieusement avec "Version not found" sur un workflow dont la chaîne de versions est corrompue, y compris en réessayant depuis l'UI n8n elle-même (pas un bug de l'outil MCP).

  • Après toute modification d'un workflow n8n déjà actif : vérifier avec get_workflow_details que versionId == activeVersionId. Si différent, le changement n'est PAS en production.
  • Si publish_workflow échoue de façon persistante (même après unpublish_workflow puis republish) : ne pas insister, dupliquer le workflow (bouton Duplicate dans l'UI n8n) — la copie repart avec une chaîne de versions saine et se publie normalement. Archiver l'original cassé (archive_workflow) une fois la copie confirmée active.

Fuseau horaire

Le NAS et n8n tournent en UTC. Tunis = UTC+1 toute l'année (pas de changement d'heure). Pour un cron en heure de Tunis, toujours retirer 1h à l'expression cron (ex: 7h/12h/20h Tunis = "0 6,11,19 * * *" en UTC).

Leçon générale

Une réponse "success" d'un outil de modification (update_workflow, edit de jobs.json) ne garantit jamais que le changement est en production. Toujours vérifier l'état réel après coup : next_run_at recalculé pour un cron Hermes, activeVersion == draft pour un workflow n8n.