# Procédure standard MacLustr — REMOTE-FIRST (en vigueur depuis le 2026-10-02) > **Règle unique : tout ce qui touche MacLustr se modifie SUR LE NŒUD CONCERNÉ, jamais sur le laptop.** > Le laptop est un terminal : il ouvre des sessions SSH, lance les wrappers (`mld`, `mlt`, `mlmobile`) et consulte des miroirs > en lecture seule (`git pull`). La source de vérité de chaque composant est le **dépôt git sur son nœud propriétaire**, dont > l'`origin` est **spbgit** (bare repos `M1M32:~/srv/git/.git`, alias SSH `gitsrv` présent sur tous les nœuds et le laptop). > Généralisation à tout le cluster de la règle appliquée aux projets Groupe Ka depuis le 2026-08-17 (`KA-REMOTE-DEV.md`). ## 1. Qui possède quoi | Composant | Nœud propriétaire | Dépôt sur le nœud | spbgit | Mise en service après modification | |---|---|---|---|---| | Orchestrateur **mld** (placement, heal, tunnel, harden) | **M1M32** | `~/maclustr-dispatch` | `maclustr-dispatch.git` | immédiat (`bin/mld`) ; `mld heal` (LaunchDaemon `io.maclustr.mld-heal`) relit le code à chaque passage | | **agentd** (API MacLustr pour apps macOS/iOS, sondes, incidents) | **M4M64a** | `~/maclustr-agentd` | `maclustr-agentd.git` | `launchctl kickstart -k gui/$(id -u)/io.maclustr.agentd` puis `curl :9210/api/summary` (version) | | **cluster-skill** (cette doc, NODES.md, inventaires, wrappers `mld`/`mlt`/`mlmobile`, `maclustr-tunnel/`, `ovh-manager/`, `dossier/`, `operateur/`) | **M1M32** | `~/cluster-skill` | `cluster-skill.git` | laptop : `git -C ~/Desktop/Cluster/cluster-skill pull` (les wrappers s'exécutent depuis ce miroir) | | **MacLustr Tunnel** (hub WireGuard, Caddy, `tunnelctl`) | **BHS64** (OVH) | `/usr/local/bin/tunnelctl`, `/etc/caddy`, `/etc/wireguard`, `/etc/maclustr-tunnel` | copie de référence `cluster-skill/maclustr-tunnel/` (à resynchroniser depuis BHS64 après modification) | `systemctl reload caddy` ; routes via `tunnelctl` | | **Manifestes et registre mld** (secrets) | **M1M32** | `~/dispatch/apps/*.json`, `~/dispatch/registry.json` | hors git (secrets) — sauvegardes `~/Desktop/Cluster/secrets/` | `mld deploy`/`mld status` | | **Apps déployées par mld** (Ka, UQO, MacLustr web, vquant, spb-cloud, qc26, pdb-api…) | nœud du registre (`mld status`) | **le dossier déployé lui-même** (`dir` du manifeste) est un clone git | `.git` | build + `pm2 restart ` sur le nœud, healthcheck local puis public | | **Apps Apple** (MacLustr macOS/iOS, Admin-Ka macOS/iOS, Ka iOS, Vrai-Prix iOS) | **exception : laptop** (Xcode, licence, signature, TestFlight) | `~/Desktop/Cluster/apple/`, `~/Desktop/Cluster/groupe-ka/apps-natives/` | `*-ios.git`, `*-macos.git` | scripts `release-*.sh` ; **l'agent `agentd.py` n'en fait pas partie** (voir M4M64a) | | **Connaissances Claude Code** (CLAUDE.md global, mémoire, commandes `/cluster*`) | laptop opérateur | `~/.claude/…` | export dans `cluster-skill/operateur/connaissances/` (`operateur/export-connaissances.sh --vers-cluster-skill`) | voir `TRANSFERT-OPERATEUR.md` | Les copies laptop (`~/Desktop/Cluster/maclustr-dispatch`, `~/Desktop/Cluster/cluster-skill`, `~/Desktop/Projets/*`, `~/Desktop/Cluster/apple/maclustr-ios-v2/agent/`) sont des **miroirs** : `git pull` pour lire, jamais d'édition ni de `git push` depuis le laptop (sauf apps Apple et export des connaissances). ## 2. Modifier un composant : la séquence 1. **Localiser** : `mld status` (app → nœud, dossier) ou le tableau ci-dessus. 2. **Lire** : `ssh "cd && git status --short && git log --oneline -5"`. Un `git status` non vide = travail en cours sur le nœud, à intégrer, pas à écraser. 3. **Éditer sur le nœud** : petits changements par `ssh 'python3 - <:/ /tmp/` → édition locale → `scp` retour. Les secrets restent dans les manifestes mld / `.env` du nœud (jamais dans git). 4. **Construire et tester sur le nœud** (les `node_modules`, venv, bases y sont) : `pnpm build` / `pytest` / …, puis `pm2 restart ` (ou `launchctl kickstart -k …` pour agentd/gardiens), healthcheck local (`curl 127.0.0.1:`) puis public (`curl https://`). 5. **Committer et pousser sur le nœud** : `ssh "cd && git add -A && git commit -m '…' && git push origin main"` (agent forwarding actif depuis le laptop). 6. **Documenter** sur M1M32 si l'inventaire ou une procédure change : `ssh M1M32 "cd ~/cluster-skill && … && git commit && git push"` puis `git pull` sur le laptop ; mettre à jour `~/.claude/CLAUDE.md` et la mémoire Claude si la règle ou la topologie change. ## 3. mld et la règle remote-first - **`mld adopt [--node X] [--repo nom] [--dry-run]`** (2026-10-02) : fait du dossier déployé un clone git (`origin` spbgit, créé s'il n'existe pas), restaure depuis `origin/main` les fichiers suivis absents du nœud (exclus du rsync : tests, exemples) et **commite l'état du nœud** (`adopt: état déployé sur …`). À faire une fois par app ; toutes les apps du registre sont adoptées au 2026-10-02. - **Garde dans `mld deploy`** : si le dossier du nœud est un dépôt git dont le HEAD diffère du staging, ou qui a des modifications non commitées, le déploiement **refuse** (le `rsync --delete` écraserait du travail). Chemin normal : `mld fetch --from ` (copie le `.git` dans le staging) puis `mld deploy`, ou `mld move` qui le fait seul. `--force` écrase sciemment. - **`mld stage `** ne sert plus qu'à **créer une app** la première fois (ou à la ressusciter depuis un dépôt) : stage → `mld deploy` → `mld adopt`. Jamais pour modifier une app existante. - Déplacer une app : `mld move --to X` (pré-copie à chaud depuis le nœud, `.git` compris, route tunnel repointée). Nouveau nœud → `mld prepare X`. ## 4. Vérifier que tout fonctionne (après toute opération) ```bash mld status --live # apps : PM2 online, santé locale/publique mld heal --dry-run # ce que l'auto-réparation ferait (doit être « 0 réparées, 0 KO ») mld tunnel status # pairs WireGuard (16 Macs) + routes Caddy sur BHS64 curl -s -H "Authorization: Bearer $(ssh M4M64a "python3 -c 'import json;print(json.load(open(\"$HOME/maclustr-agentd/config.json\"))[\"token\"])'")" http://M4M64a.maclustr.io:9210/api/summary | python3 -m json.tool | head -30 # agentd : health, servers, sites, incidents ``` ## 5. Ce qui a été fait le 2026-10-02 pour aligner l'état sur la règle - `maclustr-agentd.git` créé ; `M4M64a:~/maclustr-agentd` est un dépôt (config/lanmap/registry/history hors git) — la copie `Cluster/apple/maclustr-ios-v2/agent/` du laptop devient miroir. - `cluster-skill.git` créé ; `M1M32:~/cluster-skill` = copie canonique, `~/Desktop/Cluster/cluster-skill` = miroir (wrappers). - `mld adopt` + garde `deploy` ; 18 apps adoptées (voir journal `M1M32:~/dispatch/logs/`), dont spb-cloud et vquant dont l'`origin` GitHub (compte suspendu) a été renommé `old-origin`. - Alias `gitsrv` de M1M32 → lui-même (127.0.0.1) ; les autres nœuds visent M1M32 par le LAN.