fix: close internal semantic review gaps

This commit is contained in:
2026-08-08 23:27:58 +02:00
parent 43d8063922
commit 2c4534d968
18 changed files with 806 additions and 77 deletions
+111 -7
View File
@@ -14,17 +14,34 @@ import { validateDeclarativePiConfig } from "../src/pi/managed-config.js";
const FAKE = path.resolve("../harness/tests/fake_pi/fake_pi_rpc.mjs");
const SCRIPT = path.resolve("../harness/tests/fake_pi/scripts/f1_disambiguation.json");
function operationalWorkspace(id = "default") {
return {
workspace: { schema_version: 3, id, name: id, language: "en" },
dwh: {
engine: "postgres", database: "warehouse", schema: "public",
supported_transports: ["postgres_direct"],
},
semantic_index: {
vector_store: {
engine: "qdrant", collection: id, dimensions: 1024, distance: "cosine",
},
embedding: {
provider: "ollama_internal", model: "qwen3-embedding:0.6b", dimensions: 1024,
},
},
llm_policy: {
allowed: ["zai/glm-5.2", "deepseek/deepseek-v4-pro", "local-qwen/qwen3.6-35b-a3b"],
},
} as const;
}
const defaultWorkspaceRegistry = {
list: vi.fn(async () => [{
id: "default", commit: "e".repeat(40), blob: "f".repeat(40),
snapshotPath: `/data/workspace-registry/snapshots/${"e".repeat(40)}/default.yaml`, state: "operational",
}]),
read: vi.fn(async (id: string) => ({
workspace: {
llm_policy: {
allowed: ["zai/glm-5.2", "deepseek/deepseek-v4-pro", "local-qwen/qwen3.6-35b-a3b"],
},
},
workspace: operationalWorkspace(id),
revision: {
id, commit: "e".repeat(40), blob: "f".repeat(40),
snapshotPath: `/data/workspace-registry/snapshots/${"e".repeat(40)}/${id}.yaml`, state: "operational",
@@ -33,9 +50,13 @@ const defaultWorkspaceRegistry = {
};
function buildApp(config: Parameters<typeof buildRealApp>[0], deps: Record<string, unknown> = {}) {
const thtRunner = deps.thtRunner
? { qdrantEnsure: async () => ({ ok: true }), ...(deps.thtRunner as object) }
: undefined;
return buildRealApp(config, {
workspaceRuntimeSupport: () => true,
...deps,
...(thtRunner ? { thtRunner } : {}),
workspaceRegistry: { ...defaultWorkspaceRegistry, ...(deps.workspaceRegistry as object | undefined) },
} as any);
}
@@ -663,7 +684,7 @@ test("session lifecycle locates a B session when installation default is A", asy
],
readPinned: vi.fn(async (id: string, revision: string) => {
expect([id, revision]).toEqual(["b-workspace", "c".repeat(40)]);
return { workspace: { llm_policy: { allowed: ["zai/glm-5.2"] } }, workspaceConfigPath: bPinnedPath };
return { workspace: operationalWorkspace(id), workspaceConfigPath: bPinnedPath };
}),
} as any,
});
@@ -932,7 +953,7 @@ test("POST /sessions/:id/resume uses the manifest's retained workspace revision"
getSettings: () => ({ workspace: "legacy" }) as any,
workspaceRegistry: {
readPinned: vi.fn(async () => ({
workspace: { workspace: { id: "psd-clinical" } },
workspace: operationalWorkspace("psd-clinical"),
revision: {
id: "psd-clinical", commit: "a".repeat(40), blob: "b".repeat(40),
snapshotPath: "/data/workspace-registry/snapshots/aaaaaaaa/psd-clinical.yaml", state: "operational",
@@ -968,6 +989,61 @@ test("POST /sessions/:id/resume returns a sanitized error when its retained revi
expect(response.json()).toMatchObject({ code: "workspace_revision_unavailable" });
});
test("POST /sessions/:id/resume rejects a pinned schema-v2 workspace before readiness or runtime", async () => {
const readiness = vi.fn(async () => ({ ok: true }));
const reopenSession = vi.fn(async () => {});
const acquireWorkspaceRuntime = vi.fn();
const createFor = vi.fn();
const app = buildApp(loadConfig({ THT_HARNESS_DIR: "../harness" }), {
thtRunner: {
sessionShow: async () => ({
status: "open", archived: false,
workspace_id: "psd-clinical", workspace_revision: "a".repeat(40),
}),
reopenSession,
acquireWorkspaceRuntime,
} as any,
readiness: { ensure: readiness } as any,
mgr: { get: () => undefined, createFor } as any,
getSettings: () => ({ workspace: "legacy" }) as any,
workspaceRegistry: {
readPinned: vi.fn(async () => ({
workspace: {
workspace: { schema_version: 2, id: "psd-clinical", name: "PSD", language: "it" },
dwh: {
engine: "postgres", database: "warehouse", schema: "public",
supported_transports: ["rest_api"],
},
semantic_index: {
vector_store: {
engine: "pgvector", database: "warehouse", schema: "vectors",
collection: "documents", dimensions: 768, distance: "cosine",
supported_transports: ["rest_api"],
},
embedding: {
provider: "ollama_compatible", model: "nomic-embed-text", dimensions: 768,
},
},
llm_policy: { allowed: ["zai/glm-5.2"] },
},
workspaceConfigPath: `/data/workspace-registry/snapshots/${"a".repeat(40)}/psd-clinical.yaml`,
})),
} as any,
});
const response = await app.inject({ method: "POST", url: "/sessions/pinned-v2/resume" });
expect(response.statusCode).toBe(409);
expect(response.json()).toEqual({
code: "workspace_revision_unavailable",
error: "Session workspace configuration is unavailable. Check configuration and try again.",
});
expect(readiness).not.toHaveBeenCalled();
expect(reopenSession).not.toHaveBeenCalled();
expect(acquireWorkspaceRuntime).not.toHaveBeenCalled();
expect(createFor).not.toHaveBeenCalled();
});
test("a pruned pin blocks Resume but not active or mutation lifecycle routes", async () => {
const activePath = "/registry/snapshots/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/b-workspace.yaml";
const prunedError = "cannot read /registry/snapshots/secret-pruned-revision/b-workspace.yaml";
@@ -2340,11 +2416,35 @@ test("POST /sessions readiness failure returns one fixed public message without
expect(res.statusCode).toBe(503);
expect(res.json()).toEqual({
error: "Session services are not ready. Check configuration and connectivity, then try again.",
code: "workspace_not_activatable",
});
expect(res.body).not.toMatch(/secret\.invalid|DO_NOT_LEAK|\/srv\/private\/model-key/);
expect(createdCalled).toBe(false);
});
test.each(["semantic_index_incompatible", "workspace_not_activatable"] as const)(
"POST /sessions does not persist when Qdrant readiness returns %s",
async (code) => {
const sessionNew = vi.fn(async () => ({ id: "must-not-exist" }));
const app = buildApp(loadConfig({ THT_HARNESS_DIR: "../harness" }), {
thtRunner: { sessionNew } as any,
readiness: { ensure: async () => ({ ok: false, code }) } as any,
getSettings: () => ({ workspace: "psd" }) as any,
});
const response = await app.inject({
method: "POST", url: "/sessions", payload: { question: "q" },
});
expect(response.statusCode).toBe(503);
expect(response.json()).toEqual({
error: "Session services are not ready. Check configuration and connectivity, then try again.",
code,
});
expect(sessionNew).not.toHaveBeenCalled();
},
);
test("POST /sessions returns storage 503 before creating a Pi runtime when session persistence fails", async () => {
let piCreated = false;
const app = buildApp(loadConfig({ THT_HARNESS_DIR: "../harness" }), {
@@ -2365,8 +2465,10 @@ test("POST /sessions returns storage 503 before creating a Pi runtime when sessi
test("POST /sessions proceeds when ollamaEnsure succeeds", async () => {
let ensureWs: string | undefined;
const qdrantEnsure = vi.fn(async () => ({ ok: true }));
const app = buildApp(loadConfig({ THT_HARNESS_DIR: "../harness" }), {
thtRunner: {
qdrantEnsure,
ollamaEnsure: async (ws: string) => { ensureWs = ws; return { ok: true }; },
searchPack: async () => {},
sessionNew: async () => ({ id: "s1" }),
@@ -2376,6 +2478,7 @@ test("POST /sessions proceeds when ollamaEnsure succeeds", async () => {
});
const res = await app.inject({ method: "POST", url: "/sessions", payload: { question: "q" } });
expect(res.json()).toEqual({ id: "s1" });
expect(qdrantEnsure).toHaveBeenCalledWith(operationalWorkspace("psd"), 60);
expect(ensureWs).toContain(`/snapshots/${"e".repeat(40)}/psd.yaml`);
});
@@ -2574,6 +2677,7 @@ test("POST /sessions/:id/resume readiness failure returns the same fixed public
expect(res.statusCode).toBe(503);
expect(res.json()).toEqual({
error: "Session services are not ready. Check configuration and connectivity, then try again.",
code: "workspace_not_activatable",
});
expect(res.body).not.toMatch(/secret\.invalid|DO_NOT_LEAK|\/srv\/private\/resume-key/);
});