From 3dc4721e2a4a56a3631c839f0fff94fca3c4759c Mon Sep 17 00:00:00 2001 From: Daniel Ehrhardt Date: Sun, 25 Oct 2026 09:04:18 +0100 Subject: [PATCH 1/2] Fix CI after merging #241 and #243 together The merge left duplicate group/replica imports in remote-snapshot.test.ts, and #241's two same-name tests expected the secondary's project to be skipped. With #243 the local project steps aside to a free slug instead and both are kept, so the tests now expect that. --- packages/core/test/remote-snapshot.test.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/core/test/remote-snapshot.test.ts b/packages/core/test/remote-snapshot.test.ts index f3915ecf..deb0770e 100644 --- a/packages/core/test/remote-snapshot.test.ts +++ b/packages/core/test/remote-snapshot.test.ts @@ -10,9 +10,7 @@ import { all, closeDb, get, getMeta, insert, openDb, run as sql } from "../src/d import { bus } from "../src/events/bus"; import { setLogLevel } from "../src/log"; import type { MemorySnapshot } from "../src/memory/files"; -import { clearGroup, setGroup } from "../src/remote/group"; import { mergeMemory, readMemoryState, writeMemoryState } from "../src/remote/memorySync"; -import { ensureReplica, resetReplicaCache } from "../src/remote/replica"; import { appliedDigest, applySnapshot, buildSnapshot, snapshotDigest, type ConfigSnapshot } from "../src/remote/snapshot"; import { clearGroup, setGroup } from "../src/remote/group"; import { ensureReplica, madeHere, pendingKeys, resetReplicaCache } from "../src/remote/replica"; @@ -726,7 +724,7 @@ describe("applying a snapshot on a runner", () => { expect(vault.isUnlocked()).toBe(true); }); - test("a secondary keeps a project it made with the same name as one of the primary's, and the rest of the copy lands", async () => { + test("a secondary keeps a project it made with the same name as one of the primary's under a free slug, and the rest of the copy lands", async () => { const secondary = mkdtempSync(join(tmpdir(), "godmode-snapshot-secondary-")); try { use(controller); @@ -749,10 +747,10 @@ describe("applying a snapshot on a runner", () => { use(secondary); const result = await applySnapshot(copy); - expect(result.warnings).toEqual(['"Earshot" (projects) wasn\'t copied: this computer has its own one with the same name.']); - expect(exists("projects", "prj_here")).toBe(true); - expect(exists("projects", "prj_there")).toBe(false); - expect(row("agents", "agt_helper")).toMatchObject({ project_id: "prj_here", instructions: "Work on Earshot." }); + expect(result.warnings).toEqual([]); + expect(row("projects", "prj_here").slug).toBe("earshot-2"); + expect(row("projects", "prj_there").slug).toBe("earshot"); + expect(row("agents", "agt_helper")).toMatchObject({ project_id: "prj_there", instructions: "Work on Earshot." }); expect(appliedDigest()).toBe(copy.digest); } finally { clearGroup(); @@ -779,10 +777,11 @@ describe("applying a snapshot on a runner", () => { use(secondary); const result = await applySnapshot(copy); - expect(result.warnings.join("\n")).toContain('"Studio" (workspaces) wasn\'t copied'); + expect(result.warnings).toEqual([]); + expect(row("workspaces", "ws_here").slug).toBe("studio-2"); + expect(row("workspaces", "ws_there").slug).toBe("studio"); expect(row("projects", "prj_here")).toMatchObject({ workspace_id: "ws_here", slug: "earshot" }); - expect(exists("workspaces", "ws_there")).toBe(false); - expect(exists("projects", "prj_there")).toBe(false); + expect(row("projects", "prj_there")).toMatchObject({ workspace_id: "ws_there", slug: "earshot" }); expect(exists("agents", "agt_helper")).toBe(true); expect(appliedDigest()).toBe(copy.digest); } finally { From 111e4c6321e6f310f0f1a123c7dabcac294ab8a1 Mon Sep 17 00:00:00 2001 From: Daniel Ehrhardt Date: Sun, 25 Oct 2026 09:13:03 +0100 Subject: [PATCH 2/2] Classify the 2FA autolink routes for cloud access Reading the suggestions is allowed like GET /api/totp; linking them needs secret access like linking a 2FA code from a missing login. --- packages/core/src/cloud/scope.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/core/src/cloud/scope.ts b/packages/core/src/cloud/scope.ts index 0170bbef..7e4dc45f 100644 --- a/packages/core/src/cloud/scope.ts +++ b/packages/core/src/cloud/scope.ts @@ -106,6 +106,8 @@ const RULES: [methods: string, path: string, rule: Rule][] = [ ["GET", "/api/totp", A], ["POST", "/api/totp", S], ["GET", "/api/totp/codes", S], + ["GET", "/api/totp/autolink", A], + ["POST", "/api/totp/autolink", S], ["POST", "/api/totp/import", S], ["PATCH", "/api/totp/:id", S], ["DELETE", "/api/totp/:id", A],