feat: operator schema accept command for curated FK review (P5)

This commit is contained in:
2026-08-13 05:06:23 +02:00
parent 5249798c03
commit 0459a6cd3e
9 changed files with 293 additions and 1 deletions
@@ -4,6 +4,7 @@ import { join } from "node:path";
import { afterEach, expect, test, vi } from "vitest";
import { parseWorkspaceYaml } from "../src/workspaces/schema.js";
import { PreprocessingStateStore } from "../src/workspaces/preprocessing-state.js";
import { syncAnnotations } from "../src/workspaces/annotations-sync.js";
import {
WorkspacePreprocessingService,
type ChildProcessRequest,
@@ -349,3 +350,75 @@ test("full runs follow the explicit order and finish unchanged when no Evidence
"vector index-schema",
]);
});
test("schema accept validates the synced Git blob and records the review", async () => {
const f = fixture();
f.runChild.mockResolvedValueOnce({
exitCode: 0,
stdout: JSON.stringify({
status: "succeeded",
candidate_count: 1,
candidate_digest: "sha256:" + "e".repeat(64),
candidate_yaml: "tables: {}\n",
}),
stderr: "",
});
const suggest = await f.service.suggestFks({ workspaceId: "psd-clinical" });
const runId = suggest.runId!;
const candidateDigest = suggest.artifactIdentities![0]!.digest;
const synced = syncAnnotations({
dataRoot: f.dataRoot,
workspaceId: "psd-clinical",
commit: "a".repeat(40),
blobId: "b".repeat(40),
contents: Buffer.from("tables: {}\n"),
});
f.runChild.mockResolvedValueOnce({
exitCode: 0,
stdout: JSON.stringify({
status: "succeeded",
orphan_count: 0,
annotations_digest: synced.contentDigest,
reviewed_candidates_digest: candidateDigest,
}),
stderr: "",
});
const result = await f.service.acceptSchema({ workspaceId: "psd-clinical", runId, yes: true });
expect(result).toMatchObject({ status: "succeeded", code: "ok", operation: "schema accept" });
const state = new PreprocessingStateStore({ dataRoot: f.dataRoot, workspaceId: "psd-clinical" });
expect(state.readFkReview(runId)).toMatchObject({
reviewedCandidatesDigest: candidateDigest,
annotationsDigest: synced.contentDigest,
workspaceRevision: "a".repeat(40),
blobId: "b".repeat(40),
});
});
test("schema accept fails closed without --yes, for an unknown run, or with no synced annotations", async () => {
const f = fixture();
f.runChild.mockResolvedValueOnce({
exitCode: 0,
stdout: JSON.stringify({
status: "succeeded",
candidate_count: 1,
candidate_digest: "sha256:" + "e".repeat(64),
candidate_yaml: "tables: {}\n",
}),
stderr: "",
});
const suggest = await f.service.suggestFks({ workspaceId: "psd-clinical" });
const runId = suggest.runId!;
await expect(f.service.acceptSchema({ workspaceId: "psd-clinical", runId, yes: false }))
.resolves.toMatchObject({ status: "failed", code: "annotation_invalid" });
await expect(f.service.acceptSchema({ workspaceId: "psd-clinical", runId: "e".repeat(32), yes: true }))
.resolves.toMatchObject({ status: "failed", code: "annotation_invalid" });
await expect(f.service.acceptSchema({ workspaceId: "psd-clinical", runId, yes: true }))
.resolves.toMatchObject({ status: "failed", code: "annotation_invalid" });
expect(f.runChild).toHaveBeenCalledTimes(1);
});