Highlights
Architectural fix: single source of truth for the model registry, plus automatic OpenClaw config sync on every `ocp update`.
Why this release matters
Before v3.11.0, the model list lived in 3 places that drifted independently:
- `server.mjs` MODEL_MAP (the OCP API)
- `setup.mjs` MODELS (only ran at install time)
- User's `~/.openclaw/openclaw.json` (cached snapshot from setup.mjs, never refreshed)
Existing OpenClaw users running `ocp update` would see new `/v1/models` ids, but their OpenClaw dropdown stayed frozen at install-time models — e.g. v3.10.0's Opus 4.7 never appeared without a manual config edit.
What changed
`models.json` — Single Point of Truth
All model metadata now lives in one file at the repo root. `server.mjs` and `setup.mjs` derive their tables from it. Adding a new model is now a one-file edit.
`scripts/sync-openclaw.mjs` — idempotent reconciliation
Scoped strictly to OCP's own province in OpenClaw's registry:
- Touches only `models.providers."claude-local".models` and `agents.defaults.models["claude-local/*"]` keys
- Preserves `baseUrl`/`api`/`authHeader` on existing installs (port customization survives)
- Timestamped backup (`openclaw.json.bak.`) before every write; no-op runs skip backup
- Exits 0 silently for non-OpenClaw users (`~/.openclaw/openclaw.json` missing)
- All other providers and config keys untouched
`ocp update` — auto-sync hook
Inserted between `git pull` and proxy restart. Non-fatal: sync failure does not abort the update; `/v1/models` still works regardless.
`server.mjs` — passive drift self-check
On startup, if OpenClaw's registered model list differs from `models.json`, a `console.warn` recommends running `sync-openclaw`. Read-only; no network or endpoint surface change.
How other IDEs are affected
| IDE | How they read models | Action needed |
|---|---|---|
| OpenClaw | Cached in `openclaw.json` | ✅ `ocp update` auto-syncs |
| Cline / Aider / Cursor / opencode | Live query `/v1/models` | ✅ Already auto-fresh |
| Continue.dev | User-written `config.json` | Edit manually if you want a new model |
Adding a new model in the future
# Edit models.json, add one entry
git commit -m \"feat(models): add claude-opus-5-0\"
gh pr create # CI runs alignment.yml
# After merge:
git tag v3.x.y && git push --tags
# All users get it on next \`ocp update\` — including OpenClawOne-time bootstrap caveat (for existing v3.10.0 installs only)
The `ocp update` from v3.10.0 → v3.11.0 runs the old `cmd_update` bash function (already loaded into the running shell), so the new sync hook does NOT fire on this single jump. If your OpenClaw still shows the old 3 models after upgrading to v3.11.0, run once manually:
```bash
node ~/ocp/scripts/sync-openclaw.mjs
```
From v3.11.0 → any future version, the hook fires automatically. This affects only the 3.10.0 → 3.11.0 transition.
PRs
- #30 refactor: extract models.json as single source of truth
- #31 feat: idempotent OpenClaw registry sync in `ocp update` + passive drift self-check
- #32 chore: v3.11.0 release
Independent review
All three PRs were post-merge reviewed by Opus 4.7 with fresh context (Iron Rule 10 debt cleared). MODEL_MAP byte-equivalence verified. Cloud idempotency verified (2 consecutive runs, both no-op).