mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix: prevent externally supervised state schema drift (#121069)
* fix: prevent externally supervised state schema drift * refactor: isolate schema ownership support code * test: follow canonical additive column order * test: keep older schema fixture valid * fix: preserve additive schema compatibility * chore: remove release-owned changelog entry * test: follow schema compatibility owner * style: format schema compatibility test * refactor: split sqlite schema sql helpers * fix: preserve desktop schema compatibility * fix: preserve ownership gates across platforms * fix: preserve detached updater long paths * fix: close external state ownership races * chore: refresh plugin sdk api baseline
This commit is contained in:
committed by
GitHub
parent
bff0494f33
commit
f31d9d8fa9
@@ -29,8 +29,30 @@ OpenClaw applies forward-only migrations when it opens an older supported databa
|
||||
|
||||
Changes may stay at the same schema version only when downgraded readers remain safe. New tables qualify because older builds ignore them. An explicitly compatible column on an existing table qualifies only when its declaration is exactly one bare nullable SQLite `STRICT` datatype: `ANY`, `BLOB`, `INT`, `INTEGER`, `REAL`, or `TEXT`. The declaration cannot have a default, `NOT NULL`, a primary or unique key, a check, a reference, a collation, a generated expression, or another suffix. Constrained existing-table additions require a schema-version bump or a companion table instead.
|
||||
|
||||
Matching numeric versions are necessary but not sufficient. A release can add a lazy or startup-repairable table, column, index, or trigger without advancing `user_version`, so two databases at the same version can still have different shapes. OpenClaw validates the canonical table definitions, constraints, indexes, triggers, virtual tables, and table options owned by the running release.
|
||||
|
||||
Installing OpenClaw manually through npm bypasses the updater guard. Database open checks still refuse an incompatible build.
|
||||
|
||||
## Preflight a target release
|
||||
|
||||
Before activating or rolling back a release, run that target release's CLI against one explicit copied state database:
|
||||
|
||||
```bash
|
||||
openclaw database preflight <copied-state.sqlite> --json
|
||||
```
|
||||
|
||||
The command does not read the default state directory or mutate the supplied file. It opens the supplied consolidated file as immutable/read-only, compares the target release's own schema contract, and reports one status:
|
||||
|
||||
- `exact`: the copied database matches the target release's runtime schema. Feature-local tables that are intentionally absent until first use do not require repair.
|
||||
- `startup-repairable`: the numeric version matches and a runtime-owned additive difference remains; startup needs a write to converge the shape.
|
||||
- `migration-required`: the database is older than the target release.
|
||||
- `incompatible`: the database is newer, or its same-version shape has blocking drift such as an unexpected column.
|
||||
- `indeterminate`: the file, integrity metadata, or ownership metadata could not be verified.
|
||||
|
||||
JSON output is identified by `schema: "openclaw.state-schema-preflight.v1"`.
|
||||
|
||||
Use a SQLite online backup or another WAL-aware snapshot produced while the source is safely coordinated. The resulting preflight input must be one consolidated file with no sibling `-wal`, `-shm`, or `-journal`; sidecars make the result `indeterminate`. Do not copy only the main `.sqlite` file from an active WAL database. Preflight the exact runtime that will be activated; a package version or numeric schema version alone does not prove same-version shape compatibility.
|
||||
|
||||
## Agent schema history
|
||||
|
||||
| Version | Change | First release |
|
||||
@@ -65,7 +87,7 @@ Version 3 was an unshipped development step folded into version 4.
|
||||
| Gateway background verifier | Run the full scan about once daily and log results |
|
||||
| Doctor, backup verification, and compaction | Run the full scan before accepting or rewriting the database |
|
||||
|
||||
The Gateway preflight reads schema headers only. The background verifier owns the slower full scan for databases that do not need migration.
|
||||
The Gateway startup preflight reads schema headers only. `openclaw database preflight` performs the release-local shape comparison for an explicit copied file. The background verifier owns the slower recurring full scan for live databases that do not need migration.
|
||||
Quarantine decisions live only in a dedicated `openclaw-quarantine.sqlite` store, so they survive damage to the databases being quarantined. Verification results are logged.
|
||||
|
||||
## Troubleshooting
|
||||
@@ -86,7 +108,7 @@ Since 2026.7.2, `openclaw update` refuses to install a release that cannot open
|
||||
|
||||
A newer OpenClaw build wrote your databases, and the running build is older. The error names the refusing install — release version, commit, and install root — plus the schema it supports and the schema it found.
|
||||
|
||||
Act on the install root, not the version. One release version string spans many `main` commits and several schema levels, so two installs can both call themselves `2026.7.2` and support different schemas. A prerelease version may not exist on the `latest` npm tag at all: check `npm view openclaw dist-tags` before reinstalling, because the tag carrying the schema you need may be `beta`, and reinstalling from `latest` can move you further away.
|
||||
Act on the install root, not the version. One release version string spans many `main` commits, schema levels, and same-version schema shapes, so two installs can both call themselves `2026.7.2` and still disagree about a database. A prerelease version may not exist on the `latest` npm tag at all: check `npm view openclaw dist-tags` before reinstalling, because the tag carrying the schema you need may be `beta`, and reinstalling from `latest` can move you further away.
|
||||
|
||||
A linked source checkout is the case where the commit misleads: `openclaw --version` reports the checkout's git HEAD, but the code actually executing is whatever `dist/` was last built. If the install root is a checkout, rebuild it (`pnpm build`) before concluding the version is wrong.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user