На шлюзах Mac clustervps дрейф часто прячется за дубликатами Label в launchd, «зелёным» поверхностным doctor --json и столкновением канареечных портов со stable. Этот материал дополняет статьи про доли трафика: акцент на doctor --deep как честном service discovery, срезах портов, лаконичном резюме сбоев webhook и явном откате после каждого шага.

Читайте вместе с канареечными долями и skill-паками, поэтапным апгрейдом и peer deps, multi-AZ webhook шлюза и merge фрагментов workflow: там — математика балансировщика и semver-срезы; здесь — чтобы инвентаризация сервисов macOS не врала после копирования plist между AZ и merged readiness не «зеленела» на чужом PID.

Три боли, которые не поймать только doctor --json

  1. Дубликаты Label: два plist с одним Label и разными бинарниками — launchctl оставляет тот юнит, что загрузился первым; пробы остаются зелёными.
  2. Пересечение портов: канарейка и stable слушают 127.0.0.1:9099; merged readiness после ручного копирования plist цепляет неверный PID.
  3. Шум webhook: сырые логи скрывают короткий дайджест, который должен заморозить наращивание весов LB.

После merge шаблонов или клонов «золотого» образа запускайте openclaw doctor --deep --json и сравнивайте блок инвентаризации между AZ. Если путь отличается от эталонного узла, а поверхностный doctor зелёный — стоп: до widen канарейки вас отделяет один гоночный сценарий launchctl.

Матрица: поверхностный doctor и doctor --deep на узлах clustervps

Выберите глубину доказательств до правок launchd на арендованных Mac.

Сигнал doctor --json doctor --deep --json Заметка оператору
Скорость Секунды; безопасно в tight loop. Медленнее; обходит discovery из plist. --deep после правок plist или AMI-клонов.
Дубликаты Label Часто невидимы. Показывает конфликтующие юниты. Дифф deep JSON эталон vs канарейка до сдвига LB.
Канареечный гейт Ежедневный смоук. Обязателен после launchd. Связка с merged-пробами из гайда по rolling upgrade.

Храните shallow и deep JSON рядом с openclaw.lock и снимками весов LB: откат — это tarball плюс восстановление весов, а не расследование в чате. В таблице промоушена — одна строка на узел с именами файлов и id тикета.

Минимально воспроизводимый чек-лист (у каждого шага — откат)

Сначала один канареечный хост; рядом эталонный witness для диффа JSON.

  1. Заморозка: tarball LaunchAgents с OpenClaw и JSON весов LB. Откат: только восстановление tarball.
  2. База: doctor --json и doctor --deep --json в /tmp. Откат: прервать до правок plist.
  3. Дедуп Label: launchctl list, plutil -p по каждому plist; один Label — один plist. Откат: bootout тестового юнита, bootstrap архивного plist.
  4. Срез порта: stable 9099, канарейка — высокий блок (напр. 19199+) через EnvironmentVariables в plist; обновите фаервол хоста и заметки по security group региона. Откат: прежние ключи окружения, bootout/bootstrap старого plist.
  5. Перезагрузка и deep doctor: один цикл bootout/bootstrap; deep JSON должен совпасть с эталоном по путям и портам. Откат: связка прежнего semver и plist.
  6. Резюме по дайджесту: когда merged readiness и дайджест пересекают порог — POST однострочного резюме (см. tenant split и merge webhook). Откат: выключить notifier, вернуть окно дайджеста.
  7. Расширение: только если SHA256 пробы совпадает с пирами по гайду по канарейке. Откат: снимок LB из шага заморозки.
/usr/bin/find ~/Library/LaunchAgents /Library/LaunchAgents -name '*openclaw*' -maxdepth 1 -print
/usr/local/bin/openclaw doctor --deep --json | /usr/bin/tee "/tmp/$(/bin/hostname -s).doctor.deep.json"

Канареечные срезы портов и stable-слушатели

Оставьте stable-шлюзы на loopback 9099, чтобы привычные curl-проверки не менялись. Админку, очередь и вспомогательный endpoint дайджеста для канарейки привяжите к задокументированному высокому блоку портов — тогда merged readiness и резюме webhook всегда цепляют PID канарейки, даже если при инциденте продублировали plist. Зафиксируйте срез в той же таблице, что и строки merge фрагментов, чтобы люди и автоматизация смотрели на одну матрицу.

Широковещание: hostname, AZ, счётчик классов ошибок дайджеста, merged SHA256 — не трогайте доли LB, пока deep JSON не совпадёт с эталоном.

Сохраняем merged-пробы; после успешного deep doctor добавляем контекст дайджеста

Повторите паттерн хэша из гайда по rolling upgrade; curl направляйте на канареечный loopback-порт из вашего среза.

#!/usr/bin/env bash
set -euo pipefail
CANARY_PORT="${CANARY_PORT:-19199}"
/usr/local/bin/openclaw doctor --deep --json >/tmp/doctor.deep.json
/usr/bin/curl -fsS --max-time 3 "http://127.0.0.1:${CANARY_PORT}/v1/queue-snapshot" -o /tmp/queue.json
/usr/bin/curl -fsS --max-time 3 "http://127.0.0.1:${CANARY_PORT}/v1/webhook-digest" -o /tmp/digest.json
/usr/bin/python3 - <<'PY'
import hashlib, json, pathlib
parts = [pathlib.Path(p).read_bytes() for p in ("/tmp/doctor.deep.json","/tmp/queue.json","/tmp/digest.json")]
print(json.dumps({"ready_probe_sha256": hashlib.sha256(b"".join(parts)).hexdigest(),"canary_port": __import__("os").environ.get("CANARY_PORT","19199")}))
PY

Если SHA256 расходится, а счётчики дайджеста растут, сначала широковещание и заморозка долей — как в сценариях multi-AZ gateway webhook.

Лестница отката

  1. LB: обнулить вес канарейки.
  2. Plists: восстановить tarball; bootout/bootstrap.
  3. Бинарник: переустановить semver, проверенный на witness.
  4. Доказательство: shallow и deep doctor совпадают с эталоном до возврата долей.
1
После очистки — один активный LaunchAgent plist на каждый Label OpenClaw, не два.
10
Пример ширины высокого блока портов на AZ рядом со stable 9099.
5m
Окно дайджеста перед резюме сбоев webhook.

FAQ

bootout или delete? bootout выгружает юнит; tarball plist оставьте для восстановления.

Пропустить --deep? Рискованно после любой ручной правки plist или клонированного образа.

Batch на хосте? См. Nomad, аффинити и build lock.

Только эксплуатационные рекомендации. Пути и флаги сверяйте с закреплённым OpenClaw в openclaw.lock.
Физические шлюзы на Mac

Арендуйте Mac mini M4, чтобы безопасно репетировать doctor --deep

Тарифы и покупка на сайте доступны без обязательного входа в аккаунт; в помощи — SSH и доступ. Связанные материалы: канарейка, rolling upgrade, webhook шлюза.

Арендовать без входа в аккаунт Тарифы