fix: preserve evidence revision staleness semantics

This commit is contained in:
2026-08-09 18:45:56 +02:00
parent 266a604892
commit c7a369f436
3 changed files with 49 additions and 5 deletions
+19
View File
@@ -321,6 +321,25 @@ test("returns a 409 field conflict instead of overwriting a changed workspace",
});
});
test("maps a stale registry commit to HTTP 409 without conflict payloads", async () => {
const registry = registryFake({
publish: vi.fn(async () => {
throw new WorkspaceRegistryError("workspace_stale", "Workspace revision is stale");
}),
});
const app = appFor(registry);
const res = await app.inject({ method: "POST", url: "/workspaces/publish", payload: {
action: "update",
workspace,
baseCommit: "c".repeat(40),
baseBlob: "d".repeat(40),
} });
expect(res.statusCode).toBe(409);
expect(res.json()).toEqual({ code: "workspace_stale", message: "Workspace revision is stale." });
});
test("exports generated public artifacts without secret values", async () => {
const app = appFor(registryFake());
+24 -5
View File
@@ -408,6 +408,29 @@ test.each(["missing", "blob"])(
},
);
test("activation validates filesystem Evidence against its exact safeHead rather than checkout HEAD", async () => {
const remote = await fixture(withFilesystemEvidence(validYaml));
const registry = new WorkspaceRegistry(config(join(remote.root, "registry"), remote.remote));
await registry.bootstrap();
rmSync(join(remote.source, "workspace-content", "psd-clinical", "evidence"), {
recursive: true, force: true,
});
await git(remote.source, ["add", "-A", "workspace-content/psd-clinical/evidence"]);
await git(remote.source, ["commit", "-m", "Remove current Evidence root"]);
await git(remote.source, ["push", "origin", "main"]);
const invalidHead = await gitOutput(remote.source, ["rev-parse", "HEAD"]);
const internals = registry as unknown as {
repository: { pull(): Promise<{ head?: string }> };
activate(commit: string): Promise<void>;
};
expect((await internals.repository.pull()).head).toBe(invalidHead);
await expect(internals.activate(remote.initialCommit)).resolves.toBeUndefined();
await expect(registry.read("psd-clinical")).resolves.toMatchObject({
revision: { commit: remote.initialCommit },
});
});
test("creates an immutable descriptor revision for a content-only Evidence commit", async () => {
const remote = await fixture(withFilesystemEvidence(validYaml));
const root = join(remote.root, "registry");
@@ -454,11 +477,7 @@ test("rejects a stale API update after a content-only Evidence commit", async ()
workspace: filesystemWorkspace("psd-clinical"),
baseCommit: initial.revision.commit,
baseBlob: initial.revision.blob,
})).rejects.toMatchObject({
code: "workspace_conflict",
expected: { commit: initial.revision.commit, blob: initial.revision.blob },
actual: { commit: curatorCommit, blob: initial.revision.blob },
});
})).rejects.toMatchObject({ code: "workspace_stale" });
expect(await gitOutput(remote.root, ["--git-dir", remote.remote, "rev-parse", "HEAD"])).toBe(curatorCommit);
});