Files
archicratie-edition/docs/OPS-LOCALHOST-AUTO-SYNC.md
Archicratia 3086f333ed
All checks were successful
SMOKE / smoke (push) Successful in 6s
CI / build-and-anchors (push) Successful in 49s
CI / build-and-anchors (pull_request) Successful in 42s
Document cockpit local, NAS supervision, and ops workflow
2026-03-18 18:21:52 +01:00

1394 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OPS — Localhost auto-sync, cockpit local et supervision NAS
## Objet
Ce document remplace et prolonge la première version de larchitecture `localhost auto-sync`.
Il fige désormais **larchitecture opératoire complète** obtenue à lissue de la session de stabilisation du cockpit local dexploitation.
Le périmètre ne se limite plus à :
- garder `localhost` aligné sur `origin/main` ;
- séparer correctement le repo canonique de développement et le miroir local.
Il couvre maintenant aussi :
- le **deuxième environnement local de travail** sur `4322` ;
- le **cockpit local dexploitation** sur `4310/4311` ;
- la **supervision NAS** via `stack-health.json` ;
- l**instrumentation distante** de staging et prod via `__ops/health.json` ;
- la **lecture causale** des conteneurs critiques ;
- la **gradation des alertes** ;
- la **fraîcheur temporelle** du cache NAS.
---
## 1. Architecture finale retenue
Larchitecture locale repose désormais sur **cinq espaces / rôles distincts**.
### A. Repo canonique de développement
Chemin :
```text
/Volumes/FunIA/dev/archicratie-edition/site
```
Usage :
- développement normal ;
- branches ;
- commits ;
- PR ;
- tests manuels de nouvelles fonctionnalités ;
- exécution du serveur de dev local sur `4322`.
### B. Worktree miroir local de `main`
Chemin :
```text
~/ops-local/archicratie/localhost-worktree
```
Branche locale :
```text
localhost-sync
```
Usage :
- refléter automatiquement `origin/main` ;
- servir le **miroir local de vérité** sur `http://127.0.0.1:4321` ;
- ne jamais servir de lieu de développement de fond.
### C. Dossier dops local hors repo
Chemin :
```text
~/ops-local/archicratie
```
Usage :
- scripts ;
- logs ;
- fichiers détat ;
- cache NAS ;
- artefacts du cockpit ;
- LaunchAgents ;
- PID files.
### D. Cockpit local dexploitation
Chemin :
```text
~/ops-local/archicratie/cockpit
```
Usage :
- UI locale en `http://127.0.0.1:4310` ;
- API locale en `http://127.0.0.1:4311` ;
- lecture unifiée des états Git, LaunchAgents, serveurs Astro, staging, prod et stack NAS ;
- déclenchement dactions unitaires et composées.
### E. NAS DSM 7.3
Chemins clés :
```text
/volume2/docker/archicratie_ops
/volume2/docker/archicratie_ops/public/stack-health.json
/volume2/docker/archicratie_ops/generate-stack-health.sh
```
Usage :
- produire létat de santé des conteneurs critiques ;
- exposer un JSON simple rapatrié ensuite sur le Mac ;
- rester la source de vérité côté Docker Synology.
---
## 2. Vue densemble opératoire
### 2.1 Miroir local `4321`
Le miroir local `4321` est la **vérité de `main`**.
Flux :
1. `origin/main` avance.
2. Un script dauto-sync local fetch le repo canonique.
3. Le worktree `localhost-sync` est réaligné.
4. `astro dev` tourne depuis `~/ops-local/archicratie/localhost-worktree`.
5. `http://127.0.0.1:4321` reflète alors `main`.
### 2.2 Atelier local `4322`
Le port `4322` est le **vrai atelier de développement**.
Flux :
1. on travaille dans `/Volumes/FunIA/dev/archicratie-edition/site` ;
2. le serveur de dev local est lancé manuellement depuis ce repo ;
3. le cockpit peut le démarrer / larrêter ;
4. un agent local de sync peut réaligner le repo canonique sur `origin/main` quand la branche est `main` et propre.
### 2.3 Cockpit `4310/4311`
Le cockpit lit en continu :
- létat Git du repo canonique ;
- létat Git du miroir `localhost-sync` ;
- les réponses HTTP de `4321` et `4322` ;
- les réponses distantes staging / prod ;
- les LaunchAgents locaux ;
- les logs récents ;
- les événements opératoires ;
- le cache NAS rapatrié via SSH.
### 2.4 Supervision NAS
Le NAS génère périodiquement :
```json
stack-health.json
```
Ce fichier est ensuite rapatrié sur le Mac, mis en cache localement, puis injecté dans le cockpit.
---
## 3. Distinction conceptuelle consolidée
### 3.1 `4321 = miroir`
- automatique ;
- worktree dédié ;
- vérité de `main` ;
- ne pas utiliser pour le développement normal.
### 3.2 `4322 = atelier`
- manuel ;
- repo canonique ;
- branches et travail vivant ;
- peut être aligné automatiquement avec `origin/main` **uniquement** si le repo est propre et sur `main`.
### 3.3 `4310/4311 = cockpit`
- interface dexploitation ;
- ne sert pas le site éditorial ;
- supervise, diagnostique, orchestre et documente létat global.
---
## 4. Scripts locaux stabilisés
Le dossier `~/ops-local/archicratie` contient maintenant un ensemble cohérent de scripts.
### 4.1 Scripts du miroir `4321`
```text
~/ops-local/archicratie/auto-sync-localhost.sh
~/ops-local/archicratie/run-astro-localhost.sh
~/ops-local/archicratie/doctor-localhost.sh
~/ops-local/archicratie/install-localhost-sync.sh
```
Rôles :
- vérifier runtime et dépendances ;
- fetch `origin/main` ;
- réaligner le worktree ;
- exécuter `npm ci` si besoin ;
- redémarrer le serveur miroir ;
- produire un diagnostic global.
### 4.2 Scripts de latelier `4322`
```text
~/ops-local/archicratie/auto-sync-dev-main.sh
~/ops-local/archicratie/run-dev-4322.sh
~/ops-local/archicratie/stop-dev-4322.sh
```
Rôles :
- fetch du repo canonique ;
- réalignement automatique **seulement** si branche `main` + repo propre ;
- démarrage manuel du dev sur `127.0.0.1:4322` ;
- arrêt manuel du dev.
Principe important :
- si le repo canonique est sale, le script note `skip_dirty_main` et ne casse rien ;
- si le repo canonique est déjà aligné, le script note `noop_main_aligned`.
### 4.3 Scripts du cockpit
```text
~/ops-local/archicratie/run-cockpit.sh
~/ops-local/archicratie/stop-cockpit.sh
```
Rôle :
- démarrer / arrêter le cockpit avec son UI Vite et son API Node ;
- standardiser lexploitation pour éviter les commandes manuelles dispersées.
### 4.4 Script de rapatriement NAS
```text
~/ops-local/archicratie/pull-stack-health.sh
```
Rôle :
- ouvrir une session SSH vers le NAS ;
- lire le fichier `/volume2/docker/archicratie_ops/public/stack-health.json` ;
- le recopier localement dans :
```text
~/ops-local/archicratie/cache/stack-health.json
```
- écrire un log dexploitation.
---
## 5. Fichiers détat et journaux locaux
### 5.1 Dossier ops
```text
~/ops-local/archicratie
```
Contient notamment :
```text
astro-localhost.pid
dev-4322.pid
dev-main-4322.pid
cockpit.pid
last-sync.env
last-dev-main-sync.env
cockpit-events.jsonl
```
### 5.2 Logs utiles
```text
~/ops-local/archicratie/logs/auto-sync-localhost.log
~/ops-local/archicratie/logs/astro-localhost.log
~/ops-local/archicratie/logs/pull-stack-health.log
```
Et côté LaunchAgents :
```text
~/Library/Logs/archicratie-pull-stack-health.out.log
~/Library/Logs/archicratie-pull-stack-health.err.log
```
### 5.3 Cache NAS local
```text
~/ops-local/archicratie/cache/stack-health.json
```
Ce fichier est devenu un **artefact stratégique** :
- il permet au cockpit de lire la stack NAS sans dépendre dun appel live direct au NAS ;
- il permet une supervision plus robuste ;
- il rend possible une **alerte de fraîcheur**.
---
## 6. LaunchAgents et automatisation locale
Lautomatisation locale repose désormais sur **trois moteurs indépendants**.
### 6.1 Sync miroir
Rôle :
- tourner périodiquement ;
- réaligner le worktree `localhost-sync` ;
- maintenir `4321` fidèle à `origin/main`.
Cadence constatée :
- environ **toutes les 60 secondes**.
### 6.2 Sync dev-main
Rôle :
- surveiller le repo canonique ;
- le fetch régulièrement ;
- le réaligner si, et seulement si :
- la branche est `main` ;
- larbre de travail est propre.
Cadence constatée :
- environ **toutes les 75 secondes**.
### 6.3 Pull stack-health NAS
LaunchAgent :
```text
me.archicratie.pull-stack-health
```
Rôle :
- rapatrier le cache NAS via SSH ;
- mettre à jour le fichier local ;
- nourrir la supervision causale.
Cadence constatée :
- environ **toutes les 60 secondes**.
Pilotage manuel du LaunchAgent :
### Désactiver temporairement le rapatriement local
```bash
launchctl bootout "gui/$(id -u)" ~/Library/LaunchAgents/me.archicratie.pull-stack-health.plist
```
### Réactiver le rapatriement local
```bash
launchctl bootstrap "gui/$(id -u)" ~/Library/LaunchAgents/me.archicratie.pull-stack-health.plist
```
### Interprétation :
- bootout retire volontairement lagent du domaine utilisateur courant ;
- bootstrap recharge ce même agent dans le domaine utilisateur courant ;
- en fonctionnement nominal, cet agent doit rester actif ;
- après bootstrap, le fichier ~/ops-local/archicratie/cache/stack-health.json doit recommencer à être rafraîchi ;
- dans le cockpit, launchAgents.pullStackHealth.loaded doit redevenir true.
### Point dattention :
- bootout sert au test contrôlé, au diagnostic ciblé ou à une maintenance volontaire ;
- bootout ne constitue pas une commande dexploitation normale ;
- après tout usage de bootout, il faut restaurer létat nominal avec bootstrap.
---
## 7. SSH Mac ↔ NAS
### 7.1 Situation initiale
La copie du fichier NAS vers le Mac a rencontré plusieurs problèmes :
- nom dhôte local non résolu ;
- port SSH non standard ;
- `scp` indisponible / mal supporté dans la configuration DSM observée ;
- authentification par mot de passe trop lourde.
### 7.2 Paramètres réels retenus
- IP locale NAS : `192.168.1.20`
- port SSH : `44322`
- utilisateur : `archicratia`
### 7.3 Méthode de copie finalement retenue
Plutôt que `scp`, la méthode robuste retenue a été :
- `ssh ... 'cat /chemin/fichier' > fichier_local`
Cela a permis :
- de saffranchir du problème `scp subsystem request failed`;
- de garder un protocole simple ;
- dintégrer facilement le mécanisme dans `pull-stack-health.sh`.
### 7.4 Authentification par clé
Une clé dédiée a été générée côté Mac et installée côté NAS.
Le point bloquant nétait pas la clé elle-même, mais les permissions du `HOME` du compte Synology.
Correctif déterminant côté NAS :
- retirer les permissions `go-w` sur le `HOME` ;
- conserver :
- `~/.ssh` en `700`
- `authorized_keys` en `600`
Après cette correction :
- lauthentification par clé est devenue fonctionnelle ;
- le LaunchAgent de pull a pu fonctionner sans mot de passe.
### 7.5 Alias SSH local
Une entrée `~/.ssh/config` a ensuite permis dutiliser un alias opératoire du type :
```text
transhands-ops
```
ce qui a simplifié les scripts de pull.
---
## 8. Supervision NAS : génération de `stack-health.json`
### 8.1 Script côté NAS
Fichier :
```text
/volume2/docker/archicratie_ops/generate-stack-health.sh
```
Rôle :
- inspecter plusieurs conteneurs Docker clés ;
- écrire un JSON simple ;
- exposer cet état dans `public/stack-health.json`.
### 8.2 Exécution et droits
Constat clé :
- sans privilèges suffisants, le script peut échouer ou signaler `docker_unavailable` ;
- via le planificateur DSM 7.3, exécuté correctement, le fichier est bien régénéré.
Le comportement retenu :
- exécution via tâche planifiée DSM avec les droits nécessaires ;
- sortie du JSON écrite dans :
```text
/volume2/docker/archicratie_ops/public/stack-health.json
```
### 8.3 Problème rencontré
Un comportement bloquant est apparu :
- fichier existant possédé par `root` ;
- exécution interactive sans privilège ;
- `mv` demandant confirmation ou échouant ;
- `chmod` impossible.
Conclusion :
- la génération doit être pensée comme **opération root planifiée**, pas comme simple commande utilisateur interactive.
### 8.4 Horodatage local
Le champ `generatedAt` a dabord été produit en UTC (`...Z`), ce qui déplaisait à lexploitation locale.
Le script a été ajusté pour produire désormais une heure locale explicite, par exemple :
```text
2026-03-18T13:26:32+01:00
```
---
## 9. Périmètre de la stack NAS désormais supervisée
Le JSON NAS couvre désormais au moins les conteneurs suivants :
- `edge-traefik`
- `auth-authelia`
- `auth-lldap`
- `auth-redis`
- `archicratie-web-blue`
- `archicratie-web-green`
- `gitea-old-2026-02-09-105211`
- `gitea-act-runner`
Le cockpit les remappe en :
- `edgeTraefik`
- `authelia`
- `lldap`
- `authRedis`
- `webBlue`
- `webGreen`
- `gitea`
- `giteaActRunner`
---
## 10. Déploiement staging / prod : instrumentation `__ops/health.json`
### 10.1 Problème initial
Le cockpit savait tester :
- le HTTP public staging ;
- le HTTP public prod.
Mais il ne savait pas lire proprement **le build réellement servi** par `web_blue` et `web_green`.
### 10.2 Cause
Les conteneurs Nginx servaient bien le site, mais pas de manifeste détat applicatif dédié.
Les tentatives daccès à :
```text
/__ops/health.json
```
retournaient dabord :
- `404` côté conteneurs ;
- puis `302` via Authelia côté domaine public.
### 10.3 Solution produite
Deux modifications complémentaires ont été apportées.
#### A. Côté build / déploiement
Un script :
```text
scripts/write-ops-health.mjs
```
écrit désormais un manifeste :
```text
public/__ops/health.json
```
avec des champs du type :
- `service`
- `env`
- `upstream`
- `buildSha`
- `builtAt`
Ce manifeste est produit pendant le workflow de déploiement pour :
- staging / `web_blue`
- prod / `web_green`
#### B. Côté edge / Traefik / Authelia
Le routage a été ajusté pour que :
```text
https://staging.../__ops/health.json
https://archicratie.../__ops/health.json
```
restent **lisibles sans redirection Authelia**, tout en laissant le reste du site inchangé.
### 10.4 Correction de lheure `builtAt`
Comme pour `generatedAt`, le champ `builtAt` a été réaligné sur lheure locale France via :
```text
TZ=Europe/Paris
```
dans le workflow de déploiement.
---
## 11. Cockpit local dexploitation
### 11.1 Emplacement
```text
~/ops-local/archicratie/cockpit
```
### 11.2 Ports
- UI : `http://127.0.0.1:4310`
- API : `http://127.0.0.1:4311`
### 11.3 Démarrage
Le cockpit est lancé via :
```bash
~/ops-local/archicratie/run-cockpit.sh
```
et arrêté via :
```bash
~/ops-local/archicratie/stop-cockpit.sh
```
### 11.3 bis Mode opératoire recommandé
Le pilotage normal du cockpit doit se faire via les scripts bash dexploitation :
```bash
~/ops-local/archicratie/run-cockpit.sh
~/ops-local/archicratie/stop-cockpit.sh
```
et non via un lancement manuel dispersé du type npm run dev ou node server/index.mjs exécuté séparément.
### Justification :
- run-cockpit.sh démarre correctement lensemble du cockpit ;
- lUI et lAPI sont lancées ensemble dans le bon ordre logique ;
- lexploitation reste homogène et rejouable ;
- stop-cockpit.sh fournit un arrêt propre, cohérent avec les PID et lusage opératoire retenu.
### Autrement dit :
- 4310 = façade visuelle ;
- 4311 = moteur détat ;
- les scripts bash = méthode normale dexploitation.
### 11.4 Architecture interne
- UI React / Vite
- API Node locale
- lecture des états système via scripts, logs, fichiers JSON et `launchctl`
### 11.4 bis Source de vérité interne
Le cockpit ne repose pas sur une simple interface décorative.
La source de vérité opérationnelle est lAPI locale :
```text
http://127.0.0.1:4311/api/status
```
### LUI affichée sur :
```text
http://127.0.0.1:4310
```
nest quune projection visuelle de cet état consolidé.
### Conséquence pratique :
- si un doute existe sur lexactitude de linterface, il faut interroger directement GET /api/status ;
- cest cette réponse JSON qui fait foi pour :
- létat Git ;
- les LaunchAgents ;
- les serveurs 4321 et 4322 ;
- staging / prod ;
- la stack NAS ;
- les alertes ;
- les événements.
Cette distinction est importante : lUI montre, lAPI atteste.
### 11.5 Endpoints utiles
LAPI du cockpit expose au moins :
- `GET /api/health`
- `GET /api/status`
- `POST /api/action`
- `POST /api/event`
- `POST /api/events/clear`
### Remarques dexploitation :
- `GET /api/health` vérifie simplement que lAPI locale répond ;
- `GET /api/status` est lendpoint central de supervision ;
- `POST /api/action` déclenche une action opératoire unitaire ;
- `POST /api/event` permet décrire un événement dans lhistorique local ;
- `POST /api/events/clear` vide explicitement lhistorique des événements.
En cas de diagnostic, `GET /api/status` doit être considéré comme la lecture machine de référence.
---
## 12. Ce que le cockpit sait lire
Le cockpit agrège désormais :
### 12.1 Git
- branche du repo canonique ;
- SHA local ;
- `origin/main` ;
- état de propreté (`clean`, `modified`, `untracked`, etc.).
### 12.2 Miroir 4321
- port HTTP ;
- PID ;
- cwd du process ;
- dernier sync ;
- SHA du miroir.
### 12.3 Atelier 4322
- port HTTP ;
- PID ;
- branche du repo canonique ;
- dernier sync dev-main ;
- statut `noop_main_aligned` ou `skip_dirty_main`.
### 12.4 Staging et prod
- HTTP public ;
- lecture de `__ops/health.json` ;
- `env` ;
- `upstream` ;
- `buildSha` ;
- `builtAt`.
### 12.5 LaunchAgents
- état chargé / non chargé ;
- exit code ;
- compteur de runs.
### 12.6 Logs récents
- sync miroir ;
- sync dev-main ;
- Astro miroir ;
- Astro dev ;
- pull stack-health.
### 12.7 Stack NAS
- chemin du cache local ;
- `generatedAt` ;
- `dockerAccessMode` ;
- services détaillés.
---
## 13. Centre dalertes et hiérarchie de gravité
La supervision nest pas seulement binaire ; elle est maintenant **qualifiée**.
### 13.1 Niveau `info`
Exemple :
- `giteaActRunner` indisponible
Justification :
- cela dégrade la chaîne de pipeline / déploiement ;
- cela ne casse pas automatiquement le service public.
### 13.2 Niveau `warn`
Exemples :
- `authRedis` indisponible
- `gitea` indisponible
Justification :
- impact opératoire réel ;
- système encore potentiellement utilisable ;
- attention nécessaire.
### 13.3 Niveau `critical`
Exemples :
- cache NAS trop ancien
- services cœur réellement cassés
- rupture forte de la lecture de confiance
### 13.4 Exemple dalerte informative
Quand `gitea-act-runner` a été arrêté, le cockpit a correctement affiché :
- une alerte **Info**
- sans transformer à tort létat global du service public en catastrophe.
### 13.5 Exemple dalerte `warn`
Quand `auth-redis` a été arrêté, le cockpit a affiché :
- `Redis dauthentification indisponible`
- niveau **Attention**
- avec la stack causale montrant le conteneur `exited / unhealthy`.
### 13.6 Exemple dalerte `warn` sur la forge
Quand Gitea a été arrêté, le cockpit a affiché :
- `Forge Gitea indisponible`
- niveau **Attention**
- avec staging / prod encore sains.
---
## 14. Fraîcheur du cache NAS
### 14.1 Problème conceptuel identifié
Même avec un bon `stack-health.json`, le cockpit pouvait mentir par omission si :
- le scheduler DSM était cassé ;
- ou le pull SSH Mac était stoppé ;
- ou le cache local restait figé.
### 14.2 Solution
Une lecture dâge du cache a été ajoutée dans `buildAlerts(...)`.
Règles de seuil :
- pas dalerte si le cache est frais ;
- **warn** au-delà denviron 3 minutes ;
- **critical** au-delà denviron 6 minutes.
### 14.3 Test réel effectué
Le LaunchAgent `pull-stack-health` a été volontairement stoppé.
Résultats observés :
- dans une fenêtre intermédiaire : le cockpit a bien produit une alerte **Attention** ;
- au-delà du seuil haut : le cockpit a bien produit **Cache NAS trop ancien** avec niveau **Critique**.
Les commandes utilisées pour le test contrôlé de vieillissement du cache sont les suivantes.
### Interrompre volontairement le rapatriement local
```bash
launchctl bootout "gui/$(id -u)" ~/Library/LaunchAgents/me.archicratie.pull-stack-health.plist
```
### Restaurer le fonctionnement nominal
```bash
launchctl bootstrap "gui/$(id -u)" ~/Library/LaunchAgents/me.archicratie.pull-stack-health.plist
```
### Lecture correcte du test
### Pendant ce test :
- launchAgents.pullStackHealth.loaded peut passer à false ;
- ce nest pas une panne mystérieuse du cockpit ;
- cest leffet recherché, puisque le LaunchAgent a été volontairement déchargé ;
- le fichier ~/ops-local/archicratie/cache/stack-health.json reste alors figé à sa dernière valeur connue.
### Point dinterprétation essentiel
Le cockpit peut encore afficher une stack NAS apparemment OK tout en levant une alerte de fraîcheur warn puis critical.
Ce comportement est correct.
Il signifie :
- que le dernier cache disponible décrivait un état sain ;
- mais que ce cache est désormais trop ancien pour constituer une vérité dexploitation suffisamment fiable.
Autrement dit, le cockpit ne dit pas :
“la stack est saine avec certitude”
Il dit :
“le dernier état connu de la stack était sain, mais cette information est devenue trop ancienne pour être pleinement digne de confiance”.
### Conclusion :
- la supervision ne dépend plus uniquement de lexistence du cache ;
- elle qualifie aussi sa **fraîcheur temporelle**.
---
## 15. Actions opératoires disponibles dans le cockpit
Le cockpit fournit maintenant :
### 15.1 Actions composées
- réparer le miroir ;
- préparer latelier dev.
### 15.1 bis Composition réelle
Les actions composées ne sont pas des actions magiques indépendantes.
Elles orchestrent plusieurs actions unitaires dans un ordre déterminé.
Composition retenue :
- **réparer le miroir** :
1. exécuter `doctor-localhost`
2. exécuter le sync miroir `4321`
- **préparer latelier dev** :
1. exécuter le sync `dev-main`
2. démarrer le serveur local `4322`
Règle dexécution :
- si la première étape échoue, la chaîne sarrête ;
- la deuxième étape nest pas lancée si la première nest pas valide.
Règle de traçabilité :
- les actions composées écrivent un **événement composite** synthétique dans lhistorique ;
- les sous-actions internes peuvent être exécutées en mode silencieux pour éviter un doublonnage inutile dans le journal.
### 15.2 Actions unitaires
- lancer `doctor-localhost` ;
- forcer le sync miroir `4321` ;
- forcer le sync dev-main ;
- démarrer `4322` ;
- arrêter `4322`.
### 15.2 bis Périmètre et garde-fous
Les actions unitaires du cockpit pilotent avant tout **lexploitation locale sur le Mac**.
Elles agissent notamment sur :
- les scripts dops sous `~/ops-local/archicratie` ;
- le miroir local `4321` ;
- le serveur de dev local `4322` ;
- les états et journaux locaux.
Elles ne constituent pas un mécanisme de mutation directe de staging ou prod.
Staging et prod sont principalement :
- lus ;
- sondés ;
- comparés ;
- diagnostiqués.
Points importants :
- `démarrer 4322` et `arrêter 4322` naffectent que latelier local ;
- `sync dev-main` ne doit pas casser le repo canonique : le réalignement automatique na lieu que si le repo est sur `main` et propre ;
- certaines actions sont volontairement désactivées dans lUI selon létat courant ;
- une confirmation utilisateur peut être demandée avant déclenchement.
### 15.3 Journal dévénements
Les actions déclenchées depuis le cockpit peuvent être journalisées dans :
```text
~/ops-local/archicratie/cockpit-events.jsonl
```
### Ce journal peut contenir :
- des événements unitaires ;
- des événements composites.
### Chaque événement conserve au moins des informations du type :
- horodatage ;
- type daction ;
- libellé ;
- succès / échec ;
- code de sortie ;
- durée ;
- script concerné ;
- résumé opératoire.
### Ce journal constitue une mémoire locale dexploitation utile pour :
- relire les actions effectuées ;
- comprendre un enchaînement opératoire ;
- garder une trace minimale des gestes réalisés depuis le cockpit.
### Le cockpit sait aussi vider cet historique via lAPI dédiée :
- POST /api/events/clear
### Point important :
- vider lhistorique des événements ne supprime pas les logs techniques ;
- cela ne modifie ni les LaunchAgents, ni les PID, ni les fichiers détat, ni les repos Git ;
- cela efface uniquement la mémoire locale des événements cockpit.
---
## 16. Règles dexploitation consolidées
### 16.1 Règle dor
Le repo canonique nest pas le miroir local.
### 16.2 Règle miroir
`4321` doit raconter la vérité de `main`, pas létat du travail en cours.
### 16.3 Règle atelier
`4322` est le lieu du travail vivant, du test manuel et des branches.
### 16.4 Règle dops
Les scripts dops et LaunchAgents vivent sous `HOME`, pas sur `/Volumes/...`.
### 16.5 Règle de vérité
Un état nest réellement fiable que si lon connaît :
- le SHA ;
- le cwd ;
- le process réel ;
- la fraîcheur de la donnée ;
- la causalité de la panne.
---
## 17. Commandes de contrôle essentielles
### 17.1 SHA et branches
```bash
git -C ~/ops-local/archicratie/localhost-worktree rev-parse HEAD
git -C /Volumes/FunIA/dev/archicratie-edition/site rev-parse HEAD
git -C /Volumes/FunIA/dev/archicratie-edition/site ls-remote origin refs/heads/main
git -C ~/ops-local/archicratie/localhost-worktree branch --show-current
```
### 17.2 Cockpit
```bash
~/ops-local/archicratie/run-cockpit.sh
~/ops-local/archicratie/stop-cockpit.sh
curl -s http://127.0.0.1:4311/api/status | python3 -m json.tool | sed -n '1,260p'
```
### 17.3 Dev 4322
```bash
~/ops-local/archicratie/run-dev-4322.sh
~/ops-local/archicratie/stop-dev-4322.sh
```
### 17.4 Pull stack-health
```bash
~/ops-local/archicratie/pull-stack-health.sh
launchctl print "gui/$(id -u)/me.archicratie.pull-stack-health" | sed -n '1,120p'
cat ~/ops-local/archicratie/cache/stack-health.json
tail -n 20 ~/ops-local/archicratie/logs/pull-stack-health.log
```
# Commandes complémentaires de test contrôlé :
```bash
launchctl bootout "gui/$(id -u)" ~/Library/LaunchAgents/me.archicratie.pull-stack-health.plist
launchctl bootstrap "gui/$(id -u)" ~/Library/LaunchAgents/me.archicratie.pull-stack-health.plist
```
### 17.5 Miroir et doctor
```bash
~/ops-local/archicratie/auto-sync-localhost.sh
~/ops-local/archicratie/doctor-localhost.sh
```
---
## 18. Procédures de secours
### 18.1 Si `4321` ment
Vérifier :
- SHA du worktree ;
- process Astro ;
- cwd réel ;
- logs du miroir ;
- doctor.
### 18.1 bis Lecture correcte du symptôme
Quand `4321` “ment”, il faut dabord déterminer de quel mensonge il sagit réellement :
- le worktree nest pas aligné sur `origin/main` ;
- le bon worktree existe, mais le mauvais process sert le port `4321` ;
- le sync a bien eu lieu, mais linterface observée ne reflète pas encore le bon état.
Ordre de lecture recommandé :
1. vérifier le SHA du worktree miroir ;
2. vérifier le SHA attendu de `origin/main` ;
3. vérifier le process réellement attaché au port `4321` ;
4. vérifier le `cwd` réel de ce process ;
5. relire les logs du sync miroir et du serveur Astro ;
6. terminer par `doctor-localhost` si le doute persiste.
Principe :
- un `4321` trompeur est rarement un problème “front” ;
- cest presque toujours un problème de **SHA**, de **process**, de **cwd**, ou de **chaîne de sync**.
### 18.2 Si `4322` ne suit plus `main`
Vérifier :
- branche du repo canonique ;
- propreté de larbre ;
- logs `auto-sync-dev-main.sh`.
### 18.2 bis Ne pas confondre dérive normale et panne
Le port `4322` na pas vocation à refléter automatiquement `main` dans tous les cas.
Deux situations sont normales et ne doivent pas être interprétées comme des pannes :
- le repo canonique est sur une autre branche que `main` ;
- le repo canonique est sur `main` mais larbre est localement modifié.
Dans ces cas, le cockpit ou les scripts peuvent produire des états du type :
- `skip_dirty_main`
- ou absence de réalignement automatique
Ce comportement est volontaire.
Principe :
- `4322` est un **atelier de travail vivant** ;
- il ne doit pas être réaligné de force si cela risque décraser ou de perturber le travail local.
La bonne question nest donc pas seulement :
- “est-ce que `4322` suit `main` ?”
mais :
- “avait-il vocation à suivre `main` dans létat courant du repo ?”
### 18.3 Si le cockpit dit nimporte quoi sur le NAS
Vérifier :
- `stack-health.json` sur le NAS ;
- le planificateur DSM ;
- le LaunchAgent `pull-stack-health` ;
- la fraîcheur du cache local.
- si nécessaire, couper puis relancer explicitement le LaunchAgent avec `launchctl bootout ...` puis `launchctl bootstrap ...`.
### 18.3 bis Distinguer panne NAS, panne de rapatriement et cache périmé
Si la lecture NAS semble incohérente, il faut distinguer trois cas très différents :
#### A. Le NAS produit mal son état
Indices possibles :
- `stack-health.json` absent ou invalide côté NAS ;
- `dockerAccessMode` incohérent ;
- conteneurs signalés `docker_unavailable` ;
- problème de tâche planifiée DSM ou de privilèges côté génération.
#### B. Le NAS produit bien son état, mais le Mac ne le rapatrie plus
Indices possibles :
- `stack-health.json` correct sur le NAS ;
- cache local figé sur le Mac ;
- `launchAgents.pullStackHealth.loaded = false` ;
- logs de `pull-stack-health` arrêtés.
#### C. Le dernier cache local est encore lisible, mais il est trop ancien
Indices possibles :
- services encore affichés comme `OK` ;
- alerte de fraîcheur `warn` ou `critical` ;
- `generatedAt` ancien ;
- aucun rafraîchissement récent du cache.
La bonne méthode nest donc pas seulement de “regarder la stack”, mais de répondre successivement à trois questions :
1. le NAS génère-t-il correctement le fichier ?
2. le Mac le rapatrie-t-il encore ?
3. la donnée affichée est-elle encore fraîche ?
### 18.4 Si staging / prod nexposent plus `__ops/health.json`
Vérifier :
- le workflow de déploiement ;
- `scripts/write-ops-health.mjs` ;
- le routage Traefik / Authelia ;
- les endpoints internes `8081` / `8082`.
### 18.4 bis Méthode de tri diagnostique
Quand `__ops/health.json` nest plus lisible, il faut dabord identifier **à quel étage** se situe la panne.
#### Cas 1 — lendpoint interne est déjà en erreur
Si :
- `http://127.0.0.1:8081/__ops/health.json`
- ou `http://127.0.0.1:8082/__ops/health.json`
retourne `404` ou une autre erreur, alors le problème est plutôt :
- côté build ;
- côté contenu servi par Nginx ;
- ou côté déploiement du manifeste.
#### Cas 2 — lendpoint interne fonctionne mais le domaine public redirige ou bloque
Si linterne fonctionne, mais que le domaine public renvoie `302`, `401` ou un comportement auth inattendu, alors le problème est plutôt :
- côté Traefik ;
- côté règles de routage ;
- côté Authelia / exemptions ;
- côté exposition publique de `__ops/health.json`.
#### Cas 3 — lendpoint répond `200`, mais le contenu est incohérent
Si `__ops/health.json` existe et répond, mais que `env`, `upstream`, `buildSha` ou `builtAt` sont faux ou obsolètes, alors le problème est plutôt :
- dans la génération du manifeste ;
- dans le workflow de déploiement ;
- ou dans le moment précis où le manifeste est écrit dans limage livrée.
Principe :
- `404` interne → problème de build / image / contenu servi ;
- `302` ou `401` public → problème de routage / auth ;
- `200` mais mauvais contenu → problème de génération ou dinjection du manifeste.
---
## 19. Tests réels désormais qualifiés
Les validations suivantes ont été observées pendant la session :
- staging / prod exposent bien `__ops/health.json` en public ;
- `buildSha` et `builtAt` sont lisibles ;
- `builtAt` est revenu à lheure locale souhaitée ;
- la stack NAS est rapatriée côté Mac ;
- le cockpit sait afficher les services :
- `authRedis`
- `gitea`
- `giteaActRunner`
- arrêt du runner Gitea → alerte `info`
- arrêt de Redis auth → alerte `warn`
- arrêt de Gitea → alerte `warn`
- vieillissement artificiel du cache NAS → `warn` puis `critical`
---
## 20. État final de référence
Quand tout fonctionne correctement, létat attendu est :
- `4321` = miroir fidèle de `origin/main`
- `4322` = atelier local maîtrisé
- `4310/4311` = cockpit lisible et opératoire
- staging = build lisible via `__ops/health.json`
- prod = build lisible via `__ops/health.json`
- stack NAS = lisible via cache local frais
- alertes = hiérarchisées et causales
- actions cockpit = pilotage rapide sans confusion
---
## 21. Ce quil ne faut pas oublier
Cette architecture nest plus seulement une astuce de localhost.
Cest une **micro-ingénierie dexploitation locale complète**.
Elle repose sur :
- séparation des rôles ;
- automatisation légère mais fiable ;
- lecture causale ;
- instrumentation des sites ;
- cache NAS rapatrié ;
- cockpit local ;
- mémoire documentaire durable.
---
## 22. Résumé ultra court
### Pour voir la vérité de `main`
```text
http://127.0.0.1:4321
```
### Pour travailler vraiment
```text
/Volumes/FunIA/dev/archicratie-edition/site
```
### Pour superviser et piloter
```text
http://127.0.0.1:4310
```
### Pour lire létat machine consolidé
```text
http://127.0.0.1:4311/api/status
```
### Pour vérifier la stack NAS
```text
~/ops-local/archicratie/cache/stack-health.json
```
### Pour réparer vite
```bash
~/ops-local/archicratie/doctor-localhost.sh
~/ops-local/archicratie/auto-sync-localhost.sh
~/ops-local/archicratie/pull-stack-health.sh
```
---
## 23. Pistes futures à forte valeur
Les prochaines améliorations les plus pertinentes seraient :
- journal automatique des incidents détectés / résolus ;
- diagnostic synthétique de cause probable dans le cockpit ;
- regroupement visuel des services NAS par familles :
- service public
- authentification
- forge / déploiement ;
- raffinement documentaire dans `START-HERE.md` et doc dexploitation.
---
## Conclusion
Larchitecture locale est désormais passée :
- dun simple `localhost auto-sync`
- à un **dispositif dexploitation local complet**.
Le résultat essentiel est le suivant :
- on sait **où** se trouve la vérité ;
- on sait **quel** serveur sert quoi ;
- on sait **pourquoi** une alerte remonte ;
- on sait **comment** diagnostiquer et réparer ;
- on sait **rejouer** linstallation ;
- on a désormais une mémoire technique durable de lensemble.