22 KiB
OPS — Localhost auto-sync
Objet
Ce document fige l’architecture locale qui permet de garder le localhost éditorial aligné sur origin/main, sans dépendre de la mémoire de l’opérateur.
But recherché :
- quand une PR est mergée sur
main, le localhost doit pouvoir se réaligner automatiquement ; - le serveur local Astro doit tourner depuis un worktree dédié ;
- le dépôt de développement principal ne doit pas être pollué par ce mécanisme ;
- l’exploitation doit rester simple à diagnostiquer ;
- l’installation doit pouvoir être réappliquée proprement après oubli, incident, ou redémarrage machine.
Principes
L’architecture locale repose sur trois espaces distincts :
-
Repo canonique de développement
- Chemin :
/Volumes/FunIA/dev/archicratie-edition/site - Usage : développement normal, nouvelles fonctionnalités, corrections manuelles, branches de travail, commits, PR.
- Chemin :
-
Worktree localhost dédié
- Chemin :
~/ops-local/archicratie/localhost-worktree - Branche locale :
localhost-sync - Usage :
exécuter
astro devsur une copie locale réalignée automatiquement surorigin/main.
- Chemin :
-
Ops local hors repo
- Chemin :
~/ops-local/archicratie - Usage : scripts d’exploitation, logs, état, automatisation LaunchAgent.
- Chemin :
Pourquoi cette séparation
Il ne faut pas utiliser le dépôt de développement principal comme serveur localhost permanent.
Sinon on mélange :
- travail en cours ;
- commits non poussés ;
- essais temporaires ;
- état réellement publié sur
main.
Le résultat devient ambigu.
Le worktree localhost sert donc de miroir exécutable de main, tandis que le repo canonique reste l’espace de développement.
Vue d’ensemble
Flux logique :
origin/mainavance après merge d’une PR.- Un agent local de sync :
- fetch
origin/maindepuis le repo canonique ; - réaligne le worktree localhost ;
- exécute
npm cisi nécessaire ; - déclenche le redémarrage de l’agent Astro local.
- fetch
- Un agent Astro local :
- démarre
astro devdepuis le worktree localhost ; - écoute sur
127.0.0.1:4321.
- démarre
- Le site local accessible sur
http://127.0.0.1:4321reflète alorsmain.
Référence des chemins
Repo canonique
/Volumes/FunIA/dev/archicratie-edition/site
Worktree localhost
/Users/s-funia/ops-local/archicratie/localhost-worktree
Ops local
/Users/s-funia/ops-local/archicratie
Scripts principaux
/Users/s-funia/ops-local/archicratie/auto-sync-localhost.sh
/Users/s-funia/ops-local/archicratie/run-astro-localhost.sh
/Users/s-funia/ops-local/archicratie/doctor-localhost.sh
/Users/s-funia/ops-local/archicratie/install-localhost-sync.sh
Logs ops
/Users/s-funia/ops-local/archicratie/logs/auto-sync-localhost.log
/Users/s-funia/ops-local/archicratie/logs/astro-localhost.log
État du dernier sync
/Users/s-funia/ops-local/archicratie/last-sync.env
LaunchAgents
~/Library/LaunchAgents/me.archicratie.localhost-sync.plist
~/Library/LaunchAgents/me.archicratie.localhost-astro.plist
Logs launchd
~/Library/Logs/archicratie-localhost-sync.out.log
~/Library/Logs/archicratie-localhost-sync.err.log
~/Library/Logs/archicratie-localhost-astro.out.log
~/Library/Logs/archicratie-localhost-astro.err.log
Architecture retenue
1. Le repo canonique
Le repo canonique reste la source locale de travail :
cd /Volumes/FunIA/dev/archicratie-edition/site
C’est ici qu’on fait :
- création de branches ;
- développement ;
- tests manuels de nouvelles fonctionnalités ;
- commits ;
- pushes ;
- PR.
2. Le worktree localhost
Le localhost ne tourne pas depuis le repo canonique.
Il tourne depuis un worktree dédié :
cd ~/ops-local/archicratie/localhost-worktree
git branch --show-current
Branche attendue :
localhost-sync
Ce worktree suit origin/main via le script d’auto-sync.
3. Le dossier ops local
Les scripts d’exploitation ne doivent pas être mis dans le repo, ni sur un volume externe soumis à des restrictions de lancement.
Ils sont placés sous HOME :
~/ops-local/archicratie
Motif :
- compatibilité avec
launchd; - logs persistants ;
- visibilité claire ;
- indépendance du dépôt.
Pourquoi les scripts et le worktree localhost ne sont plus sur /Volumes/...
Deux difficultés réelles ont été rencontrées.
1. Exécution LaunchAgent depuis un volume externe
Erreur observée :
/bin/bash: /Volumes/FunIA/dev/_ops-local/archicratie/auto-sync-localhost.sh: Operation not permitted
Conclusion :
- le LaunchAgent peut échouer si le script est lancé depuis un chemin sur volume externe ;
- le plus robuste est de placer les scripts ops sous
HOME.
2. Exécution Astro depuis l’ancien localhost sous /Volumes/...
Erreur observée :
Error: EPERM: operation not permitted, open '/Volumes/FunIA/dev/archicratie-localhost/node_modules/astro/bin/astro.mjs'
Conclusion :
- l’ancien localhost situé sur
/Volumes/FunIA/dev/archicratie-localhostn’est plus une base fiable pour l’exploitation automatisée ; - le worktree localhost doit lui aussi être placé sous
HOME.
Donc :
- bon choix :
~/ops-local/archicratie - mauvais choix :
/Volumes/FunIA/dev/_ops-local/... - ancien chemin obsolète :
/Volumes/FunIA/dev/archicratie-localhost
Rôle exact du script auto-sync-localhost.sh
Le script a quatre responsabilités :
-
Vérifier l’environnement
gitbashnodenpm
-
Garantir le runtime Node
- Node
22.x - npm
10.x
- Node
-
Réaligner le worktree localhost
- fetch du repo canonique ;
- s’assurer que le worktree localhost existe ;
- checkout
localhost-sync; - reset hard sur
origin/main; - clean si nécessaire ;
npm cisi nécessaire.
-
Déclencher le redémarrage d’Astro
- relancer l’agent LaunchAgent Astro ;
- laisser
run-astro-localhost.shporter le démarrage réel du serveur.
Rôle exact du script run-astro-localhost.sh
Ce script a une responsabilité unique :
- démarrer
astro devdepuis le worktree localhost ; - sur
127.0.0.1:4321; - avec le bon runtime Node ;
- en produisant les logs Astro dédiés.
Il ne doit jamais démarrer depuis le repo canonique.
Rôle exact du script doctor-localhost.sh
Le doctor sert à produire un diagnostic lisible et opératoire sur :
- le runtime Node ;
- les LaunchAgents ;
- le worktree localhost ;
- l’alignement sur
origin/main; - l’état du serveur Astro ;
- la réponse HTTP de
localhost:4321; - les fichiers d’état et les logs.
C’est la commande de référence pour savoir si l’installation est saine.
Rôle exact du script install-localhost-sync.sh
Le script d’installation sert à reconstruire proprement toute l’architecture locale :
- écrire ou réécrire
auto-sync-localhost.sh; - écrire ou réécrire
run-astro-localhost.sh; - écrire ou réécrire les deux LaunchAgents ;
- recharger les LaunchAgents ;
- exécuter
doctor-localhost.shen fin d’installation.
C’est la commande de réinstallation standard après oubli, casse, dérive ou changement de configuration.
Runtime Node requis
Le projet exige :
{
"node": ">=22 <23",
"npm": ">=10 <11"
}
Le runtime retenu localement est donc :
/opt/homebrew/opt/node@22/bin/node
/opt/homebrew/opt/node@22/bin/npm
Vérification :
"$(brew --prefix node@22)/bin/node" -v
"$(brew --prefix node@22)/bin/npm" -v
Résultat attendu :
v22.x
10.x
LaunchAgents
L’architecture finale repose sur deux LaunchAgents, avec des responsabilités distinctes.
1. LaunchAgent sync
Fichier :
~/Library/LaunchAgents/me.archicratie.localhost-sync.plist
Rôle :
- réaligner périodiquement le worktree localhost sur
origin/main; - relancer l’agent Astro si nécessaire.
2. LaunchAgent Astro
Fichier :
~/Library/LaunchAgents/me.archicratie.localhost-astro.plist
Rôle :
- exécuter
run-astro-localhost.sh; - lancer
astro devdepuis le worktree localhost.
Contenu de référence du LaunchAgent sync
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>me.archicratie.localhost-sync</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Users/s-funia/ops-local/archicratie/auto-sync-localhost.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>60</integer>
<key>WorkingDirectory</key>
<string>/Users/s-funia</string>
<key>EnvironmentVariables</key>
<dict>
<key>HOME</key>
<string>/Users/s-funia</string>
<key>PATH</key>
<string>/opt/homebrew/opt/node@22/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
<key>LANG</key>
<string>fr_FR.UTF-8</string>
<key>LC_ALL</key>
<string>fr_FR.UTF-8</string>
</dict>
<key>StandardOutPath</key>
<string>/Users/s-funia/Library/Logs/archicratie-localhost-sync.out.log</string>
<key>StandardErrorPath</key>
<string>/Users/s-funia/Library/Logs/archicratie-localhost-sync.err.log</string>
</dict>
</plist>
Contenu de référence du LaunchAgent Astro
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>me.archicratie.localhost-astro</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Users/s-funia/ops-local/archicratie/run-astro-localhost.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
<key>WorkingDirectory</key>
<string>/Users/s-funia</string>
<key>EnvironmentVariables</key>
<dict>
<key>HOME</key>
<string>/Users/s-funia</string>
<key>PATH</key>
<string>/opt/homebrew/opt/node@22/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
<key>LANG</key>
<string>fr_FR.UTF-8</string>
<key>LC_ALL</key>
<string>fr_FR.UTF-8</string>
</dict>
<key>StandardOutPath</key>
<string>/Users/s-funia/Library/Logs/archicratie-localhost-astro.out.log</string>
<key>StandardErrorPath</key>
<string>/Users/s-funia/Library/Logs/archicratie-localhost-astro.err.log</string>
</dict>
</plist>
Installation / réinstallation des LaunchAgents
Vérifier les plists
plutil -lint ~/Library/LaunchAgents/me.archicratie.localhost-sync.plist
plutil -lint ~/Library/LaunchAgents/me.archicratie.localhost-astro.plist
Recharger proprement
launchctl bootout "gui/$(id -u)" ~/Library/LaunchAgents/me.archicratie.localhost-sync.plist 2>/dev/null || true
launchctl bootout "gui/$(id -u)" ~/Library/LaunchAgents/me.archicratie.localhost-astro.plist 2>/dev/null || true
launchctl bootstrap "gui/$(id -u)" ~/Library/LaunchAgents/me.archicratie.localhost-sync.plist
launchctl bootstrap "gui/$(id -u)" ~/Library/LaunchAgents/me.archicratie.localhost-astro.plist
launchctl kickstart -k "gui/$(id -u)/me.archicratie.localhost-sync"
launchctl kickstart -k "gui/$(id -u)/me.archicratie.localhost-astro"
Inspecter l’état
launchctl print "gui/$(id -u)/me.archicratie.localhost-sync" | sed -n '1,160p'
launchctl print "gui/$(id -u)/me.archicratie.localhost-astro" | sed -n '1,160p'
État attendu :
- pas d’erreur
Operation not permitted; - pas d’erreur
EX_CONFIG; - le LaunchAgent sync tourne périodiquement ;
- le LaunchAgent Astro peut être vu comme
running,spawn scheduledounot runningselon le moment d’observation ; - l’état réel de vérité reste le doctor et la réponse HTTP sur 4321.
Vérifications de bon fonctionnement
1. Vérifier que le worktree suit bien origin/main
git -C ~/ops-local/archicratie/localhost-worktree rev-parse HEAD
git -C /Volumes/FunIA/dev/archicratie-edition/site ls-remote origin refs/heads/main
Les deux SHA doivent être identiques.
2. Vérifier la branche du worktree localhost
git -C ~/ops-local/archicratie/localhost-worktree branch --show-current
Résultat attendu :
localhost-sync
3. Vérifier le dernier état sync
cat ~/ops-local/archicratie/last-sync.env
Exemple attendu :
LAST_SYNC_AT="2026-03-16 20:29:43"
LAST_SYNC_SHA="a1bfbf4405d1342c635caec5b219c14b83b36d5e"
LAST_SYNC_STATUS="noop"
4. Vérifier les logs de sync
tail -n 120 ~/ops-local/archicratie/logs/auto-sync-localhost.log
5. Vérifier les logs Astro
tail -n 120 ~/ops-local/archicratie/logs/astro-localhost.log
6. Vérifier qu’Astro écoute bien sur 4321
lsof -nP -iTCP:4321 -sTCP:LISTEN
7. Vérifier le processus Astro exact
PID="$(lsof -tiTCP:4321 -sTCP:LISTEN | head -n 1)"
ps -p "$PID" -o pid=,command=
lsof -a -p "$PID" -d cwd
Attendu :
- commande contenant
astro dev - cwd =
~/ops-local/archicratie/localhost-worktree
8. Vérifier le contenu servi
Exemple :
curl -s http://127.0.0.1:4321/archicrat-ia/prologue/ | grep -n "taxe Zucman"
Le texte renvoyé doit correspondre à la version attendue sur main.
9. Vérifier globalement toute l’installation
~/ops-local/archicratie/doctor-localhost.sh
Verdict attendu :
✅ aucun problème bloquant détecté
✅ aucun avertissement
Interprétation des statuts
status=updated
Le worktree localhost a été réaligné sur un nouveau SHA ou nettoyé, puis l’agent Astro a été relancé.
status=noop
Le worktree localhost était déjà aligné et le serveur local tournait correctement.
Aucun changement de contenu n’était nécessaire.
Usage normal au quotidien
Cas A — travail produit / publié
Quand on veut simplement consulter localement l’état réel de main :
- on laisse tourner les LaunchAgents ;
- on consulte
http://127.0.0.1:4321.
Dans ce mode, le localhost doit être considéré comme :
un miroir local exécutable de origin/main.
Cas B — développement de nouvelles fonctionnalités
Quand on veut modifier du code, tester un comportement, créer une branche :
cd /Volumes/FunIA/dev/archicratie-edition/site
git switch -c feat/ma-branche
npm run dev
Dans ce mode, on travaille dans le repo canonique, pas dans le worktree localhost.
Règle d’or
Il existe désormais deux usages distincts :
1. Voir ce qui est réellement sur main
Utiliser :
http://127.0.0.1:4321
qui sert depuis :
~/ops-local/archicratie/localhost-worktree
2. Développer / tester du neuf
Utiliser :
/Volumes/FunIA/dev/archicratie-edition/site
avec branche locale, commandes manuelles, tests de dev.
Ce qu’il ne faut pas faire
Ne pas développer dans le worktree localhost
Le worktree localhost est un miroir piloté.
Il peut être reset automatiquement.
Donc :
- pas de commits dedans ;
- pas de modifications de fond dedans ;
- pas de dev feature dedans.
Ne pas utiliser le repo canonique comme miroir auto-sync
Sinon on mélange :
- environnement de dev ;
- état publié ;
- serveur local permanent.
Ne pas conserver l’ancien chemin localhost comme référence
Le chemin :
/Volumes/FunIA/dev/archicratie-localhost
n’est plus la référence opérationnelle.
Il est obsolète pour cette architecture.
Ne pas déplacer les scripts ops sur un volume externe
Sinon launchd peut échouer avec :
Operation not permitted
Procédure de redémarrage machine
Après reboot, le comportement attendu est :
- les LaunchAgents se rechargent ;
- le script d’auto-sync s’exécute ;
- le worktree localhost est réaligné ;
- Astro redémarre sur
127.0.0.1:4321.
Vérification rapide après reboot
launchctl print "gui/$(id -u)/me.archicratie.localhost-sync" | sed -n '1,120p'
launchctl print "gui/$(id -u)/me.archicratie.localhost-astro" | sed -n '1,120p'
tail -n 80 ~/ops-local/archicratie/logs/auto-sync-localhost.log
lsof -nP -iTCP:4321 -sTCP:LISTEN
Procédure de secours manuelle
Forcer un resync
~/ops-local/archicratie/auto-sync-localhost.sh
Forcer un diagnostic complet
~/ops-local/archicratie/doctor-localhost.sh
Réinstaller tout le dispositif
~/ops-local/archicratie/install-localhost-sync.sh
Symptômes fréquents et diagnostic
Symptôme 1 — localhost ne montre pas les dernières modifs
Vérifier :
git -C ~/ops-local/archicratie/localhost-worktree rev-parse HEAD
git -C /Volumes/FunIA/dev/archicratie-edition/site ls-remote origin refs/heads/main
Si les SHA diffèrent :
- le sync n’a pas tourné ;
- ou le LaunchAgent sync ne s’exécute pas.
Symptôme 2 — SHA bon, mais contenu web pas à jour
Vérifier :
lsof -nP -iTCP:4321 -sTCP:LISTEN
PID="$(lsof -tiTCP:4321 -sTCP:LISTEN | head -n 1)"
ps -p "$PID" -o pid=,command=
lsof -a -p "$PID" -d cwd
Cause probable :
- Astro tourne depuis le mauvais dossier ;
- ou un ancien
astro devmanuel tourne encore ailleurs.
Symptôme 3 — LaunchAgent présent, mais rien ne tourne
Vérifier :
tail -n 80 ~/Library/Logs/archicratie-localhost-sync.err.log
tail -n 80 ~/Library/Logs/archicratie-localhost-astro.err.log
tail -n 120 ~/ops-local/archicratie/logs/auto-sync-localhost.log
tail -n 120 ~/ops-local/archicratie/logs/astro-localhost.log
Causes possibles :
- mauvais PATH ;
- Node 22 absent ;
- script non exécutable ;
- erreur dans un plist ;
- ancien chemin encore référencé ;
- worktree localhost absent ;
node_modulesnon installés dans le worktree.
Symptôme 4 — erreur Operation not permitted
Cause probable :
- script ops ou agent lancé depuis un chemin sous
/Volumes/....
Résolution :
- conserver les scripts sous
~/ops-local/archicratie.
Symptôme 5 — erreur EBADENGINE
Cause probable :
- Node 23 utilisé à la place de Node 22.
Résolution :
- forcer PATH avec
node@22dans les LaunchAgents et dans les scripts.
Symptôme 6 — erreur EPERM sur astro.mjs
Cause probable :
- Astro essaie encore de démarrer depuis l’ancien emplacement localhost ;
- ou une incohérence persiste dans les chemins des scripts.
Résolution :
- vérifier que tous les scripts pointent vers
~/ops-local/archicratie/localhost-worktree; - vérifier que
doctor-localhost.shconfirme le bon cwd ; - réinstaller via
install-localhost-sync.sh.
Commandes de contrôle essentielles
État Git
git -C ~/ops-local/archicratie/localhost-worktree 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
État LaunchAgents
launchctl print "gui/$(id -u)/me.archicratie.localhost-sync" | sed -n '1,160p'
launchctl print "gui/$(id -u)/me.archicratie.localhost-astro" | sed -n '1,160p'
État logs
tail -n 120 ~/ops-local/archicratie/logs/auto-sync-localhost.log
tail -n 120 ~/ops-local/archicratie/logs/astro-localhost.log
tail -n 80 ~/Library/Logs/archicratie-localhost-sync.err.log
tail -n 80 ~/Library/Logs/archicratie-localhost-astro.err.log
État serveur
lsof -nP -iTCP:4321 -sTCP:LISTEN
PID="$(lsof -tiTCP:4321 -sTCP:LISTEN | head -n 1)"
ps -p "$PID" -o pid=,command=
lsof -a -p "$PID" -d cwd
curl -I -s http://127.0.0.1:4321/ | head -n 5
Vérification contenu
curl -s http://127.0.0.1:4321/archicrat-ia/prologue/ | grep -n "taxe Zucman"
Décision d’exploitation finale
La politique retenue est la suivante :
- repo canonique = espace de développement ;
- worktree localhost = miroir automatique de
main; - ops sous HOME = scripts, logs, automation ;
- LaunchAgent sync = réalignement périodique ;
- LaunchAgent astro = exécution d’Astro ;
- Astro local = lancé uniquement depuis le worktree localhost.
Cette séparation rend le dispositif plus :
- lisible ;
- robuste ;
- opérable ;
- antifragile.
Résumé opératoire
Pour voir la vérité de main
Ouvrir :
http://127.0.0.1:4321
Le serveur doit provenir de :
~/ops-local/archicratie/localhost-worktree
Pour développer
Travailler dans :
/Volumes/FunIA/dev/archicratie-edition/site
avec tes commandes habituelles.
Pour réparer vite
~/ops-local/archicratie/doctor-localhost.sh
~/ops-local/archicratie/auto-sync-localhost.sh
Pour tout réinstaller proprement
~/ops-local/archicratie/install-localhost-sync.sh
Mémoire courte
Si un jour plus rien n’est clair, repartir de ces six commandes :
git -C ~/ops-local/archicratie/localhost-worktree rev-parse HEAD
git -C /Volumes/FunIA/dev/archicratie-edition/site ls-remote origin refs/heads/main
launchctl print "gui/$(id -u)/me.archicratie.localhost-sync" | sed -n '1,120p'
launchctl print "gui/$(id -u)/me.archicratie.localhost-astro" | sed -n '1,120p'
lsof -nP -iTCP:4321 -sTCP:LISTEN
~/ops-local/archicratie/doctor-localhost.sh
Et lire :
tail -n 120 ~/ops-local/archicratie/logs/auto-sync-localhost.log
tail -n 120 ~/ops-local/archicratie/logs/astro-localhost.log
Statut actuel visé
Quand tout fonctionne correctement :
~/ops-local/archicratie/localhost-worktreepointe sur le même SHA queorigin/main;astro devécoute sur127.0.0.1:4321;- son cwd est
~/ops-local/archicratie/localhost-worktree; - le contenu servi correspond au contenu mergé sur
main.
C’est l’état de référence à préserver.