title: page: "chad-ops: Health Checks and Cold-Start Recovery" nav: "chad-ops" description: main: "How to check Chad's health with chad-ops doctor and bring Chad back after a host reboot, pod restart, or cutover rollback." agent: "Operator runbook for scripts/chad-ops.sh. Use when the user asks whether Chad is healthy, why Chad is down after a reboot, or how to recover the sandbox, gateway, shim, crons, skills, credentials, or gbrain." keywords: ["chad-ops", "doctor", "recover", "cold start", "chad sandbox", "recovery runbook"] topics: ["ai_agents", "operations"] tags: ["openclaw", "openshell", "chad", "operations", "recovery"] content: type: how_to difficulty: technical_intermediate audience: ["developer", "engineer", "operator"] status: published
chad-ops: Health Checks and Cold-Start Recovery¶
scripts/chad-ops.sh is the host-side dispatcher for Chad's recurring
operations. It runs on the Mac host (it needs Docker, kubectl through the
cluster container, launchctl, and SSH to the sandbox) and is never deployed
into the pod. Every step checks current state first and skips healthy work, so
re-running an interrupted recovery finishes it.
Check Health¶
doctor is read-only. It first confirms the sandbox is reachable; if it is
not, it prints one failure naming what to check (the gateway on :8080, the
CLI mTLS certs, the handshake secret) and stops, instead of reading transport
errors as values. Then it checks:
| Check | Healthy output |
|---|---|
| Shim | shim :8901 → 200 |
| Gateway | gateway listening :18789 |
| gbrain | health score, page count, and embed coverage of 90% or more |
| Binaries | drift=0 absent=0 against chad-deploy-manifest.txt |
| Allowlist gate | allowlist gate armed (N operators) |
| Crons | 10 registered |
| Proton | proton-tool wrapper installed |
| GitHub CLI | gh authenticated (Supachad) |
| Skills | skills.load.extraDirs set |
| gbrain embed config | NVIDIA key and base URL present |
| Agent inbox | fewer than 50 error events today |
| Backups | last chad-state commit 12 hours old or newer |
Recover After a Restart¶
recover runs these steps in order, then runs doctor:
creds-syncpushes the filtered host credentials into the pod. It copies 11 keys: Proton, GitHub, Brave, NVIDIA, Anthropic, the invoker token,OPENWEBUI_API_KEY,CF_ACCESS_CLIENT_ID,CF_ACCESS_CLIENT_SECRET, andCHAD_STATE_REPO. Without the OpenWebUI and Cloudflare Access keys, everychad-webuitool fails.gh-authwrites/sandbox/.config/gh/hosts.ymlfromGITHUB_TOKEN.gh auth loginrejects the classic PAT because it lacksread:org, and the OpenClaw exec tool stripsGH_TOKENfrom the environment.chown,gbrain-fix, andproton-wraprestore ownership and the two credential wrappers that a restart drops.gbrain-configre-writes the embed config thatgbrain initclobbers.restore-datarestores workspace state fromchad-state, but only when the brain has zero pages or identity is missing. Otherwise it skips, so a surviving brain is never replaced by an older snapshot. SetCHAD_FORCE_RESTORE=1to override.restore-runtimerestores any missing[runtime]file fromchad-state(the action-gate policyauto-actions.json,queue/,memory/feedback-proposals.md) without touching files that exist. Withoutauto-actions.json, every gated action falls through toblock. It also copiesworkspace/fromchad-statewith no-clobber, which brings backMEMORY.mdand the daily notes undermemory/while leaving live files (identity, today's notes) untouched. The 2026-10-14 reboot lost 285 such files.deploypushes every manifest file, including all five custom skills and the orchestrator tools (chad-budget,chad-collect,chad-route, and others).cron-reloadre-registers the 10 crons. Ifjobs.jsonis missing, it fetchescron/jobs.jsonfromchad-statefirst.bonjour-off,skills-register,mcp-register,restart-gateway,gate-sync, andembed-backfillfinish the bring-up.
Recover After a Host Reboot¶
A Mac reboot restarts the cluster container and can leave three problems that
recover cannot fix on its own. Check them in this order.
Another gateway owns port 8080¶
If openshell sandbox list prints No sandboxes found while the chad pod is
running, check what listens on :8080:
An openshell-gateway process from dev.nemoclaw.openshell-gateway (the
0.0.116 gateway promoted during a cutover attempt) shadows the cluster's
gateway. Unload it and keep it from loading at login:
launchctl bootout gui/$(id -u)/dev.nemoclaw.openshell-gateway
launchctl disable gui/$(id -u)/dev.nemoclaw.openshell-gateway
Re-enable it with launchctl enable when the 0.0.116 cutover happens.
The CLI certs no longer match¶
invalid peer certificate: BadSignature means the host CLI's certs were
re-enrolled against a different gateway. Restore the cluster's own client
bundle, which the command verifies against :8080 before swapping:
The SSH handshake secret rotated¶
If ssh openshell-chad fails after a cluster restart, the Helm chart rotated
the handshake secret on the openshell StatefulSet while the chad pod kept the
old value:
Then run recover.
Recover a Rebuilt Binary¶
OpenShell records each allowed binary's SHA-256 on first use and denies a
changed binary afterwards (binary integrity check failed … hash changed).
A rebuilt proton-tool-bin therefore stays blocked until the sandbox starts
fresh, which the 0.0.116 cutover does. Find the reason with:
Related Docs¶
- GBrain in NemoClaw covers empty-brain detection, page restore,
and the
gbrain-dimsschema migration. - Chad Devflow Reference covers
chad-deployand the deploy manifest. - Chad Skills Catalog covers the custom skills and their policies.