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

624 lines
16 KiB
Markdown

# 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 :
- OpenAI prompt caching : https://platform.openai.com/docs/guides/prompt-caching
- OpenAI latency optimization : https://platform.openai.com/docs/guides/latency-optimization
- SQLite WAL : https://www.sqlite.org/wal.html
- SQLite PRAGMA / optimize / wal_checkpoint : https://www.sqlite.org/pragma.html
- SQLite VACUUM : https://www.sqlite.org/lang_vacuum.html
- Nmap Reference Guide : https://nmap.org/book/man.html
- Nmap port scanning options : https://nmap.org/book/port-scanning-options.html
- MCP sampling / context : https://modelcontextprotocol.io/specification/draft/client/sampling
---
## 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.
---
## 2. Footer observabilité
Le footer doit afficher des métriques compactes et utiles :
```text
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 :
```text
GET /api/system/status
GET /api/system/metrics
GET /api/system/storage
```
Exemple JSON :
```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 :
```json
{
"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
```json
{
"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 :
```text
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 :
```json
{
"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 :
```json
{
"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 :
```json
{
"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 :
```text
[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 :
```text
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
```json
{
"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 :
```text
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
- SQLite WAL : https://www.sqlite.org/wal.html
- SQLite `PRAGMA optimize` : https://www.sqlite.org/pragma.html#pragma_optimize
- SQLite VACUUM : https://www.sqlite.org/lang_vacuum.html
- Nmap reference guide : https://nmap.org/book/man.html
- OpenSSH `ssh-keyscan` : https://man.openbsd.org/ssh-keyscan
- OWASP Secrets Management Cheat Sheet : https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html
- OWASP Logging Cheat Sheet : https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html
- OpenAI prompt caching : https://platform.openai.com/docs/guides/prompt-caching
- Docker volumes : https://docs.docker.com/engine/storage/volumes/
## 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`.