mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 04:47:03 -06:00
fix(doctor): preserve upgrade ownership through metadata
Preserve shipped legacy default-agent ownership when Wizard metadata replaces the config object, and make the direct multi-agent upgrade fixture explicitly own heartbeat, system-agent, auth inheritance, fixed session storage, and ambient channels. This keeps authored current configurations fail-closed while allowing Doctor contributions and updater restarts to consume the migrated legacy owner. Evidence: 244 focused ownership assertions; dedicated pre-fix regression; JSON and shell fixture proof; targeted OXLint; clean structured autoreview; exact-head CI https://github.com/openclaw/openclaw/actions/runs/31691304326 (unrelated gateway shard passed on exact rerun). This merge signs the exact reviewed r21 tree on the isolated r20 base. It does not promote, tag, publish, or release.
This commit is contained in:
@@ -233,11 +233,28 @@ describe("scripts/lib/openclaw-test-state", () => {
|
||||
source: "env",
|
||||
},
|
||||
});
|
||||
expect(payload.config.channels.discord.enabled).toBe(true);
|
||||
expect(payload.config.channels.discord.dm).toStrictEqual({
|
||||
allowFrom: ["111111111111111111"],
|
||||
policy: "allowlist",
|
||||
expect(payload.config.agents.ownership).toBe("explicit");
|
||||
expect(payload.config.agents.defaults).toMatchObject({
|
||||
authInheritance: { agentId: "main" },
|
||||
heartbeat: { agentId: "main" },
|
||||
sessionStore: { agentId: "main" },
|
||||
systemAgent: { agentId: "main" },
|
||||
});
|
||||
expect(payload.config.bindings).toEqual([
|
||||
{ agentId: "main", match: { channel: "discord", accountId: "*" } },
|
||||
{ agentId: "main", match: { channel: "telegram", accountId: "*" } },
|
||||
{ agentId: "main", match: { channel: "whatsapp", accountId: "*" } },
|
||||
]);
|
||||
expect(Object.keys(payload.config.agents.entries)).toEqual(["main", "ops"]);
|
||||
expect(payload.config.agents).not.toHaveProperty("list");
|
||||
for (const agent of Object.values(payload.config.agents.entries)) {
|
||||
expect(agent).not.toHaveProperty("default");
|
||||
}
|
||||
expect(payload.config.channels.discord.enabled).toBe(true);
|
||||
expect(payload.config.channels.discord.dmPolicy).toBe("allowlist");
|
||||
expect(payload.config.channels.discord.allowFrom).toEqual(["111111111111111111"]);
|
||||
expect(payload.config.channels.discord.dm?.policy).toBeUndefined();
|
||||
expect(payload.config.channels.discord.dm?.allowFrom).toBeUndefined();
|
||||
expect(payload.config.channels.telegram.enabled).toBe(true);
|
||||
expect(payload.config.channels.whatsapp.enabled).toBe(true);
|
||||
} finally {
|
||||
@@ -273,6 +290,33 @@ describe("scripts/lib/openclaw-test-state", () => {
|
||||
expect(payload.secretKey).toMatch(secretKeyPattern);
|
||||
expect(payload.config).toStrictEqual({});
|
||||
|
||||
const upgradeProbe = await execFileAsync("bash", [
|
||||
"-lc",
|
||||
`${cleanupTestStateHomeTrap()}; export OPENCLAW_TEST_STATE_TMPDIR=${shellQuote(path.join(tempRoot, "upgrade-function-tmp"))}; source ${shellQuote(snippetFile)}; openclaw_test_state_create "upgrade case" upgrade-survivor; node -e 'const fs=require("node:fs"); process.stdout.write(fs.readFileSync(process.env.OPENCLAW_CONFIG_PATH,"utf8"));'`,
|
||||
]);
|
||||
const upgradeConfig = JSON.parse(upgradeProbe.stdout);
|
||||
expect(upgradeConfig.agents.ownership).toBe("explicit");
|
||||
expect(upgradeConfig.agents.defaults).toMatchObject({
|
||||
authInheritance: { agentId: "main" },
|
||||
heartbeat: { agentId: "main" },
|
||||
sessionStore: { agentId: "main" },
|
||||
systemAgent: { agentId: "main" },
|
||||
});
|
||||
expect(upgradeConfig.bindings).toEqual([
|
||||
{ agentId: "main", match: { channel: "discord", accountId: "*" } },
|
||||
{ agentId: "main", match: { channel: "telegram", accountId: "*" } },
|
||||
{ agentId: "main", match: { channel: "whatsapp", accountId: "*" } },
|
||||
]);
|
||||
expect(Object.keys(upgradeConfig.agents.entries)).toEqual(["main", "ops"]);
|
||||
expect(upgradeConfig.agents).not.toHaveProperty("list");
|
||||
for (const agent of Object.values(upgradeConfig.agents.entries)) {
|
||||
expect(agent).not.toHaveProperty("default");
|
||||
}
|
||||
expect(upgradeConfig.channels.discord.dmPolicy).toBe("allowlist");
|
||||
expect(upgradeConfig.channels.discord.allowFrom).toEqual(["111111111111111111"]);
|
||||
expect(upgradeConfig.channels.discord.dm?.policy).toBeUndefined();
|
||||
expect(upgradeConfig.channels.discord.dm?.allowFrom).toBeUndefined();
|
||||
|
||||
const trailingTmpDir = path.join(tempRoot, "function-trailing-tmp");
|
||||
const trailingProbe = await execFileAsync("bash", [
|
||||
"-lc",
|
||||
|
||||
Reference in New Issue
Block a user