feat: pin sessions to workspace revisions

This commit is contained in:
2026-08-04 04:52:06 +02:00
parent 2573d87a0e
commit 90894176b6
13 changed files with 313 additions and 80 deletions
+13 -10
View File
@@ -31,8 +31,8 @@ test("GET /settings returns effective defaults (env provider/model/thinking, fir
}
});
test("PUT /settings persists and GET reads it back", async () => {
const { app, dir } = appWithTmpSettings({}, {
test("PUT /settings does not persist personal workspace or LLM choices", async () => {
const { app, dir } = appWithTmpSettings({ PI_PROVIDER: "zai", PI_MODEL: "glm-5.2", PI_THINKING: "medium" }, {
listModels: async () => [{ provider: "zai", id: "glm-5.2", name: "GLM 5.2", reasoning: true }],
});
try {
@@ -42,13 +42,14 @@ test("PUT /settings persists and GET reads it back", async () => {
});
expect(put.statusCode).toBe(200);
const got = await app.inject({ method: "GET", url: "/settings" });
expect(got.json()).toMatchObject({ workspace: "psd", provider: "zai", model: "glm-5.2", thinking: "high" });
expect(got.json()).toMatchObject({ provider: "zai", model: "glm-5.2", thinking: "medium" });
expect(got.json()).not.toMatchObject({ workspace: "psd", thinking: "high" });
} finally {
rmSync(dir, { recursive: true, force: true });
}
});
test("settings are isolated by the authenticated repository principal", async () => {
test("settings no longer read or write principal-specific preferences", async () => {
const preferences = new Map<string, any>();
const runner = {
withPrincipal: (principal: any) => ({
@@ -73,11 +74,11 @@ test("settings are isolated by the authenticated repository principal", async ()
const alice = await app.inject({ method: "GET", url: "/settings", headers: headers("alice") });
const bob = await app.inject({ method: "GET", url: "/settings", headers: headers("bob") });
expect(alice.json()).toMatchObject({ workspace: "psd", thinking: "high" });
expect(bob.json()).not.toMatchObject({ workspace: "psd", thinking: "high" });
expect(alice.json()).toEqual(bob.json());
expect(preferences.size).toBe(0);
});
test("GET /settings seeds an empty private profile from complete legacy settings once", async () => {
test("GET /settings retains complete legacy installation defaults without seeding a private profile", async () => {
let preferences: Record<string, unknown> = {};
const writes: Record<string, unknown>[] = [];
const runner = {
@@ -104,13 +105,13 @@ test("GET /settings seeds an empty private profile from complete legacy settings
expect(first.statusCode).toBe(200);
expect(first.json()).toEqual(expected);
expect(second.json()).toEqual(expected);
expect(writes).toEqual([expected]);
expect(writes).toEqual([]);
} finally {
rmSync(dir, { recursive: true, force: true });
}
});
test("GET /settings does not overwrite an existing private profile with legacy settings", async () => {
test("GET /settings ignores stale private preferences in favor of installation defaults", async () => {
const privateSettings = {
workspace: "private", provider: "zai", model: "glm-5.2", thinking: "high",
};
@@ -130,7 +131,9 @@ test("GET /settings does not overwrite an existing private profile with legacy s
const response = await app.inject({ method: "GET", url: "/settings" });
expect(response.statusCode).toBe(200);
expect(response.json()).toEqual(privateSettings);
expect(response.json()).toEqual({
workspace: "local", provider: "local-qwen", model: "qwen3.6-35b-a3b", thinking: "low",
});
} finally {
rmSync(dir, { recursive: true, force: true });
}