fix(plugins): preserve startup compatibility version

(cherry picked from commit 357f5d3ca4)
This commit is contained in:
Vincent Koc
2026-08-07 08:25:49 +08:00
parent d7957d1bdf
commit bdde3d1c6d
4 changed files with 48 additions and 1 deletions
@@ -154,6 +154,22 @@ describe("runPostCorePluginConvergence", () => {
});
});
it("uses an explicit compatibility host version for startup convergence", async () => {
const cfg = { plugins: { entries: {} } } as unknown as OpenClawConfig;
await runPostCorePluginConvergence({
cfg,
env: { OPENCLAW_COMPATIBILITY_HOST_VERSION: "2026.5.12" },
compatibilityHostVersion: "2026.7.2-beta.7",
});
expect(mocks.repairMissingConfiguredPluginInstalls).toHaveBeenCalledWith({
cfg,
env: {
OPENCLAW_COMPATIBILITY_HOST_VERSION: "2026.7.2-beta.7",
OPENCLAW_UPDATE_POST_CORE_CONVERGENCE: "1",
},
});
});
it("returns ok when no warnings/failures and includes repair changes", async () => {
mocks.repairMissingConfiguredPluginInstalls.mockResolvedValue({
changes: ['Repaired missing configured plugin "discord".'],
@@ -151,6 +151,7 @@ function formatPeerLinkPackageReadWarning(failure: { error: unknown }): PostCore
export async function runPostCorePluginConvergence(params: {
cfg: OpenClawConfig;
env: NodeJS.ProcessEnv;
compatibilityHostVersion?: string;
/**
* Optional in-memory install records from earlier post-core steps (e.g.
* `syncPluginsForUpdateChannel`, `updateNpmInstalledPlugins`) whose
@@ -165,7 +166,7 @@ export async function runPostCorePluginConvergence(params: {
}): Promise<PostCoreConvergenceResult> {
const env: NodeJS.ProcessEnv = {
...params.env,
OPENCLAW_COMPATIBILITY_HOST_VERSION: VERSION,
OPENCLAW_COMPATIBILITY_HOST_VERSION: params.compatibilityHostVersion ?? VERSION,
[UPDATE_POST_CORE_CONVERGENCE_ENV]: "1",
};
const prunedBaseline = params.baselineInstallRecords
@@ -8,6 +8,7 @@ import {
formatPluginVerificationDiagnostic,
type DegradedPlugin,
} from "../plugins/runtime-degraded-state.js";
import { resolveCompatibilityHostVersion } from "../version.js";
import { measureDoctorConfigPreflightStep } from "./doctor-config-preflight-measure.js";
type StartupPluginVerificationDiagnostic = {
@@ -95,6 +96,7 @@ export async function runStartupUpgradeConvergence(params: {
runPostCorePluginConvergence({
cfg: params.cfg,
env: params.env,
compatibilityHostVersion: resolveCompatibilityHostVersion(params.env),
baselineInstallRecords: plan.installRecords,
}),
params.measure,
@@ -639,6 +639,7 @@ describe("runDoctorConfigPreflight state migration", () => {
expect(runPostCorePluginConvergence).toHaveBeenCalledWith({
cfg: { gateway: { mode: "local", port: 19091 } },
env: process.env,
compatibilityHostVersion: expect.any(String),
baselineInstallRecords: {},
});
expect(recordSuccessfulStartupMigrations).toHaveBeenCalledWith({
@@ -649,6 +650,33 @@ describe("runDoctorConfigPreflight state migration", () => {
expect(startupMigrationLeaseRelease).toHaveBeenCalledOnce();
});
it("pins startup plugin convergence to the explicit compatibility host version", async () => {
needsStartupMigrationCheckpoint.mockReturnValue(true);
const previousHostVersion = process.env.OPENCLAW_COMPATIBILITY_HOST_VERSION;
process.env.OPENCLAW_COMPATIBILITY_HOST_VERSION = "2026.7.2-beta.7";
try {
await runDoctorConfigPreflight({
migrateLegacyConfig: false,
invalidConfigNote: false,
requireStartupMigrationCheckpoint: true,
});
} finally {
if (previousHostVersion === undefined) {
delete process.env.OPENCLAW_COMPATIBILITY_HOST_VERSION;
} else {
process.env.OPENCLAW_COMPATIBILITY_HOST_VERSION = previousHostVersion;
}
}
expect(runPostCorePluginConvergence).toHaveBeenCalledWith({
cfg: { gateway: { mode: "local", port: 19091 } },
env: expect.any(Object),
compatibilityHostVersion: "2026.7.2-beta.7",
baselineInstallRecords: {},
});
});
it("refuses startup when plugin migration inputs change during convergence", async () => {
needsStartupMigrationCheckpoint.mockReturnValue(true);
pluginMigrationFingerprint