0fbca06d3d
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>
624 lines
16 KiB
Markdown
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`.
|