diff --git a/docs/installation.md b/docs/installation.md index 0d4b8ee513..19c742cb20 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -61,9 +61,10 @@ create backups, use atomic replacement, and verify their result. Setup and uninstall retain an existing `.rea.backup` rather than replacing the first snapshot. If that snapshot differs from the current configuration, setup and uninstall preserve a verified `.rea.backup..recovery` copy of the current bytes -before editing; setup also previews it. Both snapshots remain available; a -failed update, readback, or rollback names the backup path that holds the bytes -from just before that edit. +before editing; setup also previews it. Both snapshots remain available. +When an edit made a backup, a failed uninstall update or restore, and a failed +setup readback or rollback, name the backup path that holds the bytes from just +before that edit. Setup also retains valid environment overrides in REA's existing server entry, such as `REA_MCP_INPUT_SCHEMA_PROFILE`, `REA_MCP_OUTPUT_SCHEMA_PROFILE`, and `REA_MCP_MAX_RESPONSE_BYTES`. diff --git a/tests/boundary/filesystem/clientConfigurationTransactions.test.ts b/tests/boundary/filesystem/clientConfigurationTransactions.test.ts index 1e3b1d733b..70cbbbd082 100644 --- a/tests/boundary/filesystem/clientConfigurationTransactions.test.ts +++ b/tests/boundary/filesystem/clientConfigurationTransactions.test.ts @@ -138,6 +138,37 @@ describe("uninstall backups after edits made since setup", () => { expect(await readFile(configPath, "utf8")).toBe(beforeUninstall); expect(await readFile(recoveryPath, "utf8")).toBe("occupied by other data"); }); + + it.each([ + ["missing", async () => undefined], + [ + "wrong", + (_source: string, destination: string) => + writeFile(destination, "not the current configuration", { + flag: "wx", + }), + ], + ] as const)( + "blocks removal when the reported copy leaves %s backup bytes", + async (_label, copy) => { + const { root, configPath, client, beforeUninstall } = + await editedSinceSetup("rea-uninstall-current-backup-unverified-"); + let writes = 0; + const result = await systemUninstallHost(root, { + ...fileSystem("update"), + copy, + writeText: async () => { + writes += 1; + }, + }).removeClient(client); + expect(result.status).toBe("failed"); + expect(result.detail).toMatch( + /^Configuration could not be backed up, so no change was made\. /, + ); + expect(writes).toBe(0); + expect(await readFile(configPath, "utf8")).toBe(beforeUninstall); + }, + ); }); it("accepts a literal UTF-8 replacement character without changing its value", async () => {