doctor voit un service fantôme que le noyau n’expose plus. Ce HowTo pose des étapes minimales reproductibles : purge des doublons, doctor --deep pour la découverte, tranche de ports réservée au canari, puis broadcast d’une synthèse courte des échecs webhook — sans en faire le seul signal de promotion.
Lisez d’abord les playbooks complémentaires : canari multi-AZ, tranches de skills et sondes fusionnées pour les ratios et la readiness agrégée ; passerelles multi-AZ et webhooks pour le notificateur digest ; fragments locataires, Doctor et digest pour le découpage YAML. Ici l’angle est volontairement « infra d’abord » : si launchd et la découverte --deep mentent, les sondes fusionnées des autres articles affichent un vert trompeur.
Prérequis (trois Mac passerelles ou deux + notificateur)
Même compte système sur chaque hôte, même révision Git étiquetée, journaux horodatés en UTC. Notez les chemins canoniques des plist (/Library/LaunchDaemons vs copies dans /usr/local) et archivez les fichiers avant toute modification. Pour la suite des upgrades semver et peer deps, enchaînez avec roulant 2026.4.x et rollback canari une fois l’infra saine.
Checklist : supprimer les labels launchd en double
- Lister :
sudo launchctl list | grep -i openclawpuissudo launchctl print system/com.openclaw.gateway(adapter le label) sur chaque nœud ; conservez la sortie dans/var/db/openclaw/audit/launchd-snap-*.txt. - Repérer les doublons : deux fichiers plist différents qui déclarent le même
Label— souvent un template d’image figée et une copie « locale » ajoutée par un runbook. - Désactiver la copie obsolète :
sudo launchctl bootout system/com.openclaw.gateway(adapter le domaine), retirez physiquement le plist dupliqué, ne gardez qu’une définition référencée par votre CM. - Recharger :
sudo launchctl bootstrap system /Library/LaunchDaemons/com.openclaw.gateway.plistpuis un seulkickstart -kpour éviter deux PID qui se disputent le même socket.
#!/usr/bin/env bash
set -euo pipefail
LABEL="system/com.openclaw.gateway"
/usr/bin/sudo /bin/launchctl print "${LABEL}" | /usr/bin/tee "/tmp/launchd.${LABEL//\//_}.txt"
/usr/bin/sudo /usr/bin/find /Library/LaunchDaemons /usr/local -name '*openclaw*.plist' -print 2>/dev/null
Refusez toute promotion canari tant que les trois sorties ne montrent pas exactement un plist actif par Label sur chaque Mac. Sinon le « broadcast » d’échecs webhook mélange les journaux de deux démons concurrents.
doctor --deep : découverte de services et nettoyage
Le mode profond interroge les ports déclarés, les sockets UNIX et les dépendances launchd croisées avec le graphe OpenClaw. Exécutez-le sur chaque passerelle après la checklist launchd, puis comparez les JSON (outil de diff de votre choix). Ce que vous cherchez : une entrée « healthy » côté API alors qu’aucun processus n’écoute, ou l’inverse — un listener orphelin hérité d’un ancien bootstrap.
#!/usr/bin/env bash
set -euo pipefail
TENANT="${TENANT:-acme}"
/usr/local/bin/openclaw doctor --tenant "${TENANT}" --deep --json | /usr/bin/tee "/tmp/doctor-deep-${TENANT}.json"
/usr/sbin/lsof -nP -iTCP -sTCP:LISTEN | /usr/bin/grep -E 'openclaw|8088|18088' || true
Corrigez les divergences (ProgramArguments, variables d’environnement, chemins de socket) avant d’ouvrir une tranche de ports canari ; sinon vous validerez un build sur un pipe qui disparaît au prochain reboot.
Tranche de ports canari (repro minimal)
Fixez un couple stable : par exemple 8088 pour la prod et 18088 pour l’ombre canari sur un seul Mac avant de répliquer. L’équilibreur ou le sidecar healthcheck pointe vers 127.0.0.1:18088/readyz pendant que le trafic utilisateur reste sur 8088. Cette tranche est orthogonale aux ratios LB décrits dans le guide canari : ici vous isolez le bind réseau, là vous isolez le poids de session.
- Déclarez la variable ou le fragment YAML du canari (ex.
OPENCLAW_GATEWAY_HTTP_ADDR=:18088) dans le plist unique validé à l’étape précédente. - Vérifiez
curl -fsS http://127.0.0.1:18088/readyzpuis comparez la charge avec la prod sur une charge de test synthétique. - Documentez le mapping dans le même dépôt que fusion de gabarits fragmentés et workflows canari pour éviter qu’un merge YAML ne réintroduise le port prod sur l’ombre.
Synthèse courte des échecs webhook (broadcast)
Le notificateur agrège les erreurs HTTP des partenaires sur une fenêtre glissante (par ex. cinq minutes) et pousse un JSON compact vers votre canal d’astreinte : compteurs par code, top routes, corrélation trace_id. Ce broadcast répond à « que s’est-il passé pendant le canari ? » sans remplacer Doctor ni semver. Gardez-le append-only côté stockage et reliez-le à la sonde fusionnée comme champ informatif, comme dans les guides webhook et tenant déjà cités.
Rollback : ordre inverse, une seule source de vérité
- Trafic : ramenez d’abord les poids LB ou les routes GeoDNS vers la tranche
8088stable (instantané archivé). - Skills / lock : restaurez
currentetopenclaw.lockcomme dans le guide rolling upgrade. - launchd : si vous aviez retiré un plist, restaurez l’ensemble cohérent archivé — jamais deux versions mélangées.
- Vérification :
doctor --deep --jsonpuisreadyzsur le port prod uniquement ; attendez deux intervalles de sonde avant de déclarer la fin d’incident.
#!/usr/bin/env bash
set -euo pipefail
./lb_restore_weights.sh /var/db/openclaw/audit/last_good_weights.json
sudo /bin/ln -sfn "/var/db/openclaw/skills/${ROLLBACK_SEMVER}" /var/db/openclaw/skills/current
sudo launchctl bootout system/com.openclaw.gateway || true
sudo launchctl bootstrap system /Library/LaunchDaemons/com.openclaw.gateway.plist
sudo launchctl kickstart -k system/com.openclaw.gateway
/usr/local/bin/openclaw doctor --tenant acme --deep --json | /usr/bin/head -c 4000
FAQ courte
Dois-je relancer le canari skills si doctor --deep est rouge ? Non : corrigez launchd et la découverte d’abord ; le guide skills suppose une base saine.
Le broadcast suffit-il pour autoriser une promotion ? Non : il informe l’astreinte ; la barrière reste semver + Doctor + SLO charge.
Où stocker les snapshots plist ? Sous /var/db/openclaw/audit/ avec la date et le hostname dans le nom de fichier.
doctor et les chemins plist varient selon vos versions ; validez sur votre build. Les extraits shell sont des motifs — adaptez labels, ports et tenants.
Mac dédiés clustervps pour répéter ce runbook
Consultez les forfaits, la aide et l’accueil : tout est lisible sans connexion. Pour ajouter un nœud parallèle ou une passerelle canari, ouvrez directement la page achat et provisionnez du bare metal Apple Silicon aligné sur vos AZ.