---
name: openclaw-upgrade
description: Safe OpenClaw version upgrade with regression checklist. Use when kcn says "升级 openclaw" / "openclaw 有没有更新" / "/openclaw-upgrade", or after noticing a newer npm version. Checks for in-flight crons, uses the built-in updater, reapplies all host-local dist patches, and runs the full regression gate without reducing context, skills, tools, thinking, or token budgets. Different from `openclaw-tune` (periodic maintenance, no version bump).
---

# OpenClaw Safe Upgrade

Kcn runs a live automated trading system on OpenClaw. An upgrade that loses crons, breaks embeddings, or orphans an in-flight cron is a production incident. This is the battle-tested flow (5.28→6.1→6.5→6.6→6.8). The current host runbook is `/root/.shared-memory/project-openclaw-upgrade-runbook.md`; historical version traps are in the archive it links. Read these only on this host, never copy them into the public repository.

## 0. Check + decide
1. `openclaw --version` vs `npm view openclaw version` (latest). Pull the changelog (`npm pack openclaw@<v>` → `package/CHANGELOG.md`) and judge relevance — don't upgrade reflexively.
2. Read the host runbook above for the target version's traps; use the installed version's changelog/source when the runbook has no entry.

## 1. 🔴 Never restart the gateway while a cron is in-flight
Use the structured runtime field, not a text grep:

```bash
openclaw cron list --json \
  | jq -e '[.jobs[] | select(.state.runningAtMs != null)] | length == 0'
```

If this is not `true`, wait. A SIGTERM mid-run can orphan the cron into
permanent `running`. Use `--no-restart` and pick a quiet window between slots
(`bash ops/host/check_crons.sh --timeline`).

## 2. Update (built-in updater, since 6.x)
```
openclaw update --tag <version> --no-restart --yes
```
This auto-reinstalls/links managed plugins (weixin, llama-cpp, codex) — no manual `pnpm add`, no systemd edits, no `restore-llama-embeddings.sh` needed. (Pre-6.x manual flow is in the memory file.)

## 3. 🔴 Reapply all upgrade-sensitive local patches before restart
The updater replaces the installed `dist/` tree. From the live workspace run:

```bash
bash ops/host/reapply_openclaw_patches.sh
```

The versioned patch kit owns the entire dist edit set. Its ordered inventory and
per-bundle postconditions are in `ops/host/openclaw-patches/manifest.json`; source
adapters live beside it (the two Python dreaming adapters remain under `ops/host/`).
The historical scripts under `/root/tools/openclaw/current/` are not upgrade inputs.
Do not edit or invoke them to update the managed kit.

Run `bash ops/host/reapply_openclaw_patches.sh --plan` first to rehearse against
isolated copies. It resolves each bundle unambiguously, runs all ten adapters and
checks postconditions and JavaScript syntax before any installed bundle is written.
`apply` retains a transaction receipt and recovery copies; on write failure it
restores the pre-run bytes. A process kill can leave a prepared receipt: use the
hash-guarded rollback command in `docs/operations/openclaw-patch-kit.md` before
retrying. A multi-file install is not one atomic filesystem operation; keep the
gateway idle and do not restart until the whole wrapper succeeds.

The JSON report identifies the package version, manifest and adapter hashes, patch
IDs, and before/after bundle hashes. A version outside `validated_versions` is a
compatibility-review signal, not automatic proof of safety from passing anchors.
For supported native upstream fixes, record the accepted postconditions in the
manifest; do not delete a failing patch just to pass the gate.

MiniMax `service_tier: "priority"` was retired on 2026-10-19: MiniMax bills it at
1.5x the standard rate against the Token Plan. Do not reapply
`patch-minimax-m3-priority.sh`.

It also replays `ops/host/install_skillhub_plugin.sh` and `ops/host/install_memory_corpus_plugin.sh`, restoring the two versioned host extensions outside pnpm. The skill registry policy is stable system context, never a user-turn prefix. `--check-only` verifies the installed extension bytes as well.

The kit checks each patch on its specific bundle (including the header deadline value
and every dreaming race forwarding hop), then runs `node --check`. It does **not**
restart the gateway. `--check-only` rehearses the kit without writing installed files;
any proposed edit means the installation is not yet aligned.

Any missing script, changed source anchor, syntax error, or missing marker is a
hard stop: do not restart and do not declare the upgrade complete. Inspect the
new OpenClaw source, revise the relevant patch script deliberately, and rerun
the wrapper. Never skip a failed patch just to make the new version start.

## 4. Restart once, in a clean window
Re-run the structured no-in-flight check from step 1, then:

```bash
openclaw gateway restart
bash ops/host/reapply_openclaw_patches.sh --check-only
```

## 5. Regression gate (ALL must pass before declaring done)
| Check | Command | Pass = |
|---|---|---|
| version | `openclaw --version` | shows target |
| **cron contract** | `openclaw cron list --json`; `clawock system check`; `bash ops/host/check_crons.sh --timeline` | names, schedules, enabled state, payloads and host triggers match `config/cron-schedules.json`; inspect the cron runtime/watchdog contract results, not only the total count |
| embedding | `openclaw memory search "<q>" --max-results 2 --json` | returns results, no `Unknown memory embedding provider` (6.8 has no `--limit`) |
| local patches | `bash ops/host/reapply_openclaw_patches.sh --check-only` | all local patches' markers and JS/Python syntax pass |
| MiniMax transport | transport log + fallback smoke | Anthropic protocol; `priority` present; a no-header timeout is retryable; the 300s generation timeout remains |
| weixin delivery | tail `/tmp/openclaw/openclaw-*.log` | `weixin monitor started` + `gateway ready`, no crash loop |
| model chain | the cron run log / a throwaway `openclaw agent` call | a model answers (⚠️ see note) |
| clean startup | gateway log + structured cron listing | scheduler starts the contract's enabled OpenClaw jobs; no plugin load errors |

The contract currently declares 11 job identities, with 10 enabled in OpenClaw.
`港股午后快报` remains stored but disabled there: since #1443 its host crontab
trigger (`33 13 * * 1-5 clawock cron-trigger --job-name "港股午后快报"`)
queues it instead. A listing of 10 enabled jobs is not a lost job; verify the
disabled identity and the host trigger together. Do not import legacy jobs or
enable it merely to make a count pass. Derive future expectations from the contract.

Run one complete isolated cron after the cheap checks. Inspect its actual
session and `systemPromptReport`, not only the final summary. Pass means:

- all allowed workspace bootstrap files are present with `truncatedFiles=0`
- the full skill catalog is present and the payload-required `SKILL.md` body
  was actually read before analysis
- the full tool set is present (no stale cron `tools` allowlist)
- normal prompt/context window, output budget, thinking level, and whole-turn
  timeout are unchanged
- postflight reports zero issues and the expected delivery/dashboard results
- the model fallback chain still advances on a retryable provider failure

Do not use `--light-context`, a tool allowlist, lower thinking, smaller token
budgets, or prompt trimming as an upgrade workaround. MiniMax token usage is
not a constraint for this deployment.

## 6. Known-benign post-6.8 noise (don't chase)
- `adp-openclaw` plugin disabled (ships TS source, no `dist/`) — stale `plugins.entries` warning; harmless, offer to delete the entry.
- systemd unit shows "installed by <old ver>" — cosmetic metadata; daemon runs the new global package. `openclaw doctor --repair` fixes it (non-blocking).
- `plugins.allow is empty` audit WARN — long-standing, harmless.

## ⚠️ Model fallback chain (verify, escalate to kcn)
The model chain breaks silently from billing/auth, not upgrades. If cron runs show `FallbackSummaryError: All models failed`, check each provider (MiniMax overload, glm/deepseek balance, openai/anthropic auth expiry, openai-proxy quota) and tell kcn which to top up / re-login — you can't fix billing/auth yourself. See `openclaw-xiaomi-fallback`.
