Files
system_update/tache7.md
T
gilles 0fbca06d3d docs: roadmap tâches 1.9-8 (briefs, gates de validation, designs tâche 2) + plans d'implémentation
Cartographie complète (liste_taches/coherence_taches), briefs tacheN + gates
validation_tacheN, design tâche 2 (docs/design/tache2/), specs/plans jalon 1-2
et tâche 1.9/2 (Phase 1, Phase 2, SJ-0→3). Validations consignées (1.9 , 2-8 🟡).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 19:50:25 +02:00

16 KiB

Consigne de dev — Optimisation, observabilité, tokens Hermes, nettoyage DB et découverte machines

Type : mission d'investigation + design optimisation (PAS d'implémentation). Langue : français. Livrable final attendu : spec prête à passer en plan d'implémentation.


0. Contexte

Cette tâche regroupe les optimisations transverses de system_update :

  • suivi RAM/CPU/base de données dans le footer ;
  • optimisation des tokens échangés avec Hermes sans perte de donnée ;
  • auto-nettoyage de la base et des logs anciens ;
  • découverte de machines disponibles lors de l'ajout, notamment scan du port SSH 22 ;
  • sécurisation des mots de passe, secrets et entrées sensibles.

À lire avant de travailler :

  • CLAUDE.md
  • tache5.md (backend, historique JSON, automatisations)
  • tache6.md (Hermes, MCP, skills)
  • shared/types.ts
  • server/db/schema.ts
  • server/index.ts
  • server/jobs/worker.ts
  • client/src/styles/app.css
  • design_system/consigne_design_system.md

Sources web utiles :


1. Objectif

Concevoir une couche d'optimisation et d'observabilité qui permette :

  • de voir l'état technique de la webapp dans le footer ;
  • de remonter des métriques simples par machine pour les tuiles et Hermes ;
  • de limiter les tokens envoyés à Hermes tout en conservant toutes les données brutes côté webapp ;
  • de réduire la taille de la base et des logs anciens avec une politique contrôlée ;
  • de découvrir automatiquement des machines candidates sur le réseau local lors de l'ajout ;
  • de renforcer la gestion des mots de passe et secrets côté UI/backend.

Le footer doit afficher des métriques compactes et utiles :

SYSTEM UPDATE · 4 machines · APT 12 · Docker 2 · CPU 8% · RAM 214 MB · DB 42 MB · WAL 3 MB · Jobs 1 · 06:42

Métriques minimales :

  • nombre de machines ;
  • updates APT totales ;
  • updates Docker totales ;
  • jobs en cours ;
  • CPU process/backend ;
  • RAM process/backend ;
  • taille DB SQLite ;
  • taille WAL/SHM si SQLite WAL ;
  • dernier nettoyage ;
  • état Hermes : connected/disconnected ;
  • état scheduler : running/paused.

Ces métriques concernent le backend system_update, pas le monitoring détaillé des hôtes distants.

Métriques simples par machine

Prévoir en complément un snapshot machine_metrics_simple par machine :

  • CPU : load average + nombre de coeurs ;
  • RAM : total/utilisé/disponible ;
  • disque : df -h lisible et valeurs en bytes ;
  • inodes ;
  • uptime ;
  • température optionnelle si disponible.

Usage :

  • badge/alerte dans la tuile machine ;
  • rapport global Hermes ;
  • détection simple disque plein avant upgrade ;
  • pré-check avant Docker prune ou full-upgrade.

Ce n'est pas un remplaçant à Prometheus/Netdata : seulement une mesure légère, agentless, via SSH.

Le design doit respecter le design system :

  • police Share Tech Mono ;
  • cellules compactes ;
  • icônes via ui-kit si besoin ;
  • pas de couleurs hors tokens ;
  • tooltips sur métriques peu évidentes.

API à concevoir :

GET /api/system/status
GET /api/system/metrics
GET /api/system/storage

Exemple JSON :

{
  "server": {
    "status": "ok",
    "uptimeSeconds": 4200,
    "cpuPercent": 8.2,
    "memoryRssBytes": 224395264,
    "memoryHeapUsedBytes": 58200000
  },
  "database": {
    "path": "./data/system-update.db",
    "sizeBytes": 44040192,
    "walBytes": 3145728,
    "shmBytes": 32768,
    "lastOptimizeAt": "2026-06-05T06:00:00Z"
  },
  "jobs": {
    "running": 1,
    "queued": 0,
    "lastScheduleAt": "2026-06-05T06:00:00Z"
  },
  "hermes": {
    "status": "connected",
    "lastHealthAt": "2026-06-05T06:41:00Z"
  }
}

3. Sécurisation mots de passe et secrets

Objectif :

  • éviter toute fuite de mot de passe SSH/sudo/token ;
  • améliorer l'UX de saisie sans diminuer la sécurité ;
  • préparer la transition vers clés SSH et politiques de rotation.

À concevoir :

  • stockage chiffré au repos déjà existant à conserver et renforcer ;
  • séparation mot de passe SSH / mot de passe sudo ;
  • option "sudo identique au mot de passe SSH" côté formulaire, sans duplication visible ;
  • bouton afficher/masquer local dans le champ, jamais de log ;
  • validation minimale : champ vide, port, utilisateur ;
  • masquage systématique dans logs, terminal, rapports, erreurs API, Hermes/MCP ;
  • rotation des credentials par machine ;
  • test de connexion après modification ;
  • audit d'accès aux secrets ;
  • jamais de secret dans UpdateSnapshot, ExecutionResult, rapports Markdown, prompts Hermes, MCP tools ;
  • interdire stockage navigateur/localStorage/sessionStorage ;
  • préparer support clés SSH :
    • clé privée chiffrée ;
    • passphrase optionnelle ;
    • fingerprint ;
    • validation host key ;
    • ProxyJump futur ;
  • préparer auth webapp future :
    • réseau de confiance au MVP ;
    • reverse proxy/TLS/VPN ;
    • option comptes utilisateurs/MFA à documenter.

Exemple JSON public machine, sans secret :

{
  "machineId": "vm_mqtt",
  "auth": {
    "method": "password",
    "username": "gilles",
    "hasSudoPassword": true,
    "lastCredentialTestAt": "ISO",
    "credentialStatus": "ok"
  }
}

Erreurs à prévoir :

  • credential_missing
  • credential_decrypt_failed
  • ssh_auth_failed
  • sudo_auth_failed
  • host_key_changed
  • secret_redaction_failed

Le design doit préciser comment masquer les motifs sensibles dans :

  • stdout/stderr ;
  • exceptions backend ;
  • terminal live ;
  • rapports ;
  • notifications ;
  • payloads Hermes.

4. Optimisation tokens Hermes sans perte de données

Principe :

Ne jamais perdre la donnée. Archiver le brut, stocker le JSON complet, envoyer à Hermes un résumé déterministe compact avec références permettant de recharger le détail via MCP.

La webapp doit conserver :

  • log brut complet ;
  • JSON complet ;
  • rapport Markdown ;
  • historique ;
  • diff réel ;
  • erreurs structurées.

Hermes reçoit par défaut :

  • snapshot réduit ;
  • lignes importantes ;
  • compteurs ;
  • risques ;
  • références (snapshotId, executionId, reportRef) ;
  • liens MCP pour charger le détail à la demande.

Méthodes de réduction

Le design doit prévoir :

  • reducers déterministes par domaine :
    • APT ;
    • Docker ;
    • post-install ;
    • reboot ;
    • erreurs ;
  • déduplication :
    • APT : os_family + package + from + to + origin ;
    • Docker : image + fromDigest + toDigest ;
    • post-install : profileId + version + status ;
  • pagination MCP ;
  • champs courts mais explicites ;
  • tri stable ;
  • IDs/références au lieu de répéter les blocs ;
  • envoi du diff plutôt que snapshot complet quand Hermes connaît déjà l'état précédent ;
  • résumés hiérarchiques :
    • global ;
    • machine ;
    • action ;
    • erreur ;
  • outils MCP get_detail pour recharger ce qui manque.

Prompt caching

Les docs OpenAI recommandent de mettre le contenu statique au début des prompts pour bénéficier du cache de préfixe.

Design attendu :

  • préfixe stable Hermes :
    • rôle ;
    • règles sécurité ;
    • contrat JSON ;
    • mode opératoire ;
  • données variables à la fin ;
  • ne pas injecter les logs bruts dans le préfixe ;
  • mesurer cached_tokens quand le fournisseur le renvoie ;
  • garder les tool schemas stables.

Exemple payload réduit Hermes

{
  "kind": "global_update_summary",
  "generatedAt": "ISO",
  "machines": [
    {
      "id": "vm_mqtt",
      "name": "vm_mqtt",
      "status": "updates_available",
      "apt": { "count": 4, "rebootRequired": false },
      "docker": { "updates": 1, "pruneBytes": 734003200 },
      "refs": {
        "snapshotId": "snap_123",
        "latestExecutionId": "exec_456"
      }
    }
  ],
  "dedup": {
    "aptGroups": 3,
    "dockerGroups": 1
  }
}

Hermes peut ensuite appeler :

get_machine_snapshot(machineId, snapshotId)
get_machine_execution(machineId, executionId)
get_report(reportRef)

5. Mesure et budget tokens

Prévoir une table ou collection hermes_usage :

  • session ;
  • runId ;
  • promptTokens ;
  • cachedTokens ;
  • completionTokens ;
  • totalTokens ;
  • payloadKind ;
  • payloadBytes ;
  • reductionRatio ;
  • model/provider si disponible.

Exemple :

{
  "runId": "hermes_run_1",
  "payloadKind": "global_update_summary",
  "rawBytes": 940000,
  "reducedBytes": 18000,
  "promptTokens": 5200,
  "cachedTokens": 2100,
  "completionTokens": 900,
  "reductionRatio": 0.019
}

Objectifs :

  • savoir combien coûte un rapport global ;
  • détecter les payloads trop gros ;
  • ajuster les reducers ;
  • éviter une dérive silencieuse.

6. Auto-nettoyage base de données et logs

Objectif :

  • conserver l'historique utile ;
  • éviter une base ou un dossier reports/ qui grossit indéfiniment ;
  • préserver les rapports importants ;
  • permettre export avant purge.

Politique de rétention

Paramètres à concevoir :

{
  "retention": {
    "rawLogsDays": 30,
    "snapshotsDays": 90,
    "executionsDays": 180,
    "reportsDays": 365,
    "importantMessagesDays": 730,
    "keepFailedExecutionsDays": 365,
    "keepUnacknowledgedWarningsForever": true,
    "keepPinnedReportsForever": true
  }
}

Règles :

  • ne jamais supprimer un rapport épinglé ;
  • garder plus longtemps les erreurs ;
  • garder plus longtemps les messages importants extraits des logs ;
  • ne pas supprimer automatiquement les warnings non acquittés sur évolution majeure, sécurité, dépôt obsolète ou dépréciation ;
  • conserver les derniers N snapshots par machine même si anciens ;
  • purge en tâche planifiée ;
  • rapport de purge en JSON ;
  • mode dry-run obligatoire avant suppression manuelle.

Les logs bruts peuvent être supprimés avant les messages importants. Les messages extraits doivent garder :

  • source (apt, docker, post_install, ssh) ;
  • catégorie ;
  • sévérité ;
  • résumé sans secret ;
  • référence vers le log si encore présent ;
  • statut acquitté/non acquitté ;
  • date de première et dernière observation.

SQLite maintenance

SQLite WAL est déjà utilisé dans le projet.

À spécifier :

  • PRAGMA optimize périodique ;
  • PRAGMA wal_checkpoint(TRUNCATE) après purge importante ;
  • VACUUM seulement en maintenance contrôlée, car il peut être coûteux et nécessite de l'espace temporaire ;
  • suivi dbBytes, walBytes, freelistCount ;
  • politique de sauvegarde avant purge majeure.

Exemple tâche :

{
  "action": "database_cleanup",
  "mode": "dry_run",
  "deleteCandidates": {
    "rawLogs": 120,
    "snapshots": 450,
    "executions": 12
  },
  "estimatedBytesReclaimable": 734003200
}

7. Découverte de machines lors de l'ajout

Ajouter dans l'UI "Ajouter une machine" un bouton :

[scanner le réseau]

But :

  • trouver des hôtes avec port SSH ouvert ;
  • afficher une liste de candidats ;
  • préremplir hostname/IP/port ;
  • permettre test de connexion.

Méthodes de découverte

MVP recommandé :

  • scan d'un CIDR configuré : 10.0.0.0/22 ;
  • détecter port 22/tcp ouvert ;
  • récupérer host key via ssh-keyscan ou équivalent ;
  • optionnel : reverse DNS / mDNS ;
  • affichage candidates dans la webapp.

Avec Nmap :

nmap -p 22 --open 10.0.0.0/22

nmap doit être considéré ici comme outil d'administration réseau contrôlé, pas comme outil offensif. Le scan est limité aux CIDR autorisés et à des ports explicitement configurés.

Pour une intégration backend :

  • utiliser sortie XML -oX - et parser proprement ;
  • ne pas parser du texte humain si une sortie structurée est disponible ;
  • limiter fréquence et concurrence ;
  • timeout ;
  • allowlist réseau ;
  • confirmation utilisateur.

Alternative sans nmap :

  • scanner TCP simple côté Node ;
  • plus portable mais moins riche ;
  • suffisant pour port 22 ouvert ;
  • pas de fingerprint OS/service.

Le design doit comparer MVP nmap vs TCP scanner maison.

JSON candidats

{
  "scanId": "scan_1",
  "cidr": "10.0.0.0/22",
  "startedAt": "ISO",
  "finishedAt": "ISO",
  "status": "ok",
  "candidates": [
    {
      "host": "10.0.0.3",
      "port": 22,
      "service": "ssh",
      "hostKeyFingerprint": "SHA256:...",
      "reverseDns": "vm_mqtt.home",
      "alreadyKnown": false
    }
  ]
}

Sécurité découverte réseau

  • scan uniquement sur plages autorisées en paramètres ;
  • désactivé par défaut hors réseau local ;
  • journaliser scans ;
  • pas de scan agressif ;
  • pas de détection intrusive ;
  • bouton manuel ou schedule explicitement activé.

8. Paramètres optimisation

Créer une section paramètres :

Paramètres
├─ Observabilité
│  ├─ afficher CPU/RAM/DB dans footer
│  ├─ intervalle refresh métriques
│  └─ seuils warning
├─ Hermes / tokens
│  ├─ mode payload compact
│  ├─ limite tokens par rapport
│  ├─ reducers actifs
│  └─ mesurer usage tokens
├─ Nettoyage
│  ├─ rétention logs
│  ├─ rétention snapshots
│  ├─ rétention warnings importants
│  ├─ conserver warnings non acquittés
│  ├─ purge auto
│  └─ dry-run
├─ Secrets
│  ├─ rotation credentials
│  ├─ masquage logs
│  ├─ méthode auth password/ssh-key
│  └─ host key policy
└─ Découverte réseau
   ├─ CIDR autorisés
   ├─ port SSH
   ├─ méthode nmap/TCP
   └─ timeout

9. Livrables attendus

À produire sous docs/ :

  1. Design footer observabilité.
  2. Contrat /api/system/metrics.
  3. Stratégie réduction tokens Hermes sans perte de données.
  4. Contrat de mesure usage tokens.
  5. Politique de rétention DB/logs/rapports.
  6. Plan maintenance SQLite.
  7. Design découverte machines SSH.
  8. Comparatif nmap vs scanner TCP.
  9. Paramètres optimisation.
  10. Spec sécurisation mots de passe/secrets.
  11. Politique de conservation des messages importants non acquittés.
  12. Découpage en sous-jalons.

10. Définition de terminé

  • Le footer métriques est spécifié.
  • Les données brutes restent archivées.
  • Hermes reçoit un payload compact mais rehydratable.
  • La mesure tokens est prévue.
  • L'auto-nettoyage DB/logs est sûr et configurable.
  • Les messages importants restent analysables même après purge des logs bruts.
  • La découverte de machines SSH est spécifiée avec garde-fous.
  • Les mots de passe/secrets sont masqués, chiffrés, testables et jamais envoyés à Hermes/MCP.
  • Aucun code de production n'est livré pendant cette mission de design.

11. Technos à utiliser — checklist

  • SQLite maintenance : WAL, checkpoint, optimize, vacuum contrôlé.
  • Reducers déterministes avant Hermes.
  • Mesure usage tokens Hermes.
  • nmap optionnel pour découverte contrôlée.
  • Scanner TCP maison comme alternative MVP.
  • ssh-keyscan ou équivalent pour fingerprints.
  • Chiffrement secrets au repos.
  • Redaction logs/UI/Hermes/MCP.
  • Schedules de cleanup.
  • Metrics backend exposées via API.
  • Docker volumes compatibles purge/logs.

12. URLs utiles

13. Liens parent/enfant avec les autres tâches

  • Parents :
    • tache5.md pour API/jobs/rétention.
    • tache1.9.md pour tables metrics/cleanup/discovery.
    • tache6.md pour Hermes/tokens.
  • Enfants :
    • tache3.md pour footer, smartphone et paramètres.
    • tache8.md pour cache local, tokens client et metrics.
  • Validation : validation_tache7.md.