fix: align workspace diagnostic contracts
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
createWorkspaceDiagnoser,
|
||||
type DiagnosticAdapters,
|
||||
} from "../src/workspaces/diagnostics.js";
|
||||
import { resolveRuntimeBindings } from "../src/workspaces/bindings.js";
|
||||
import type { RuntimeBindings } from "../src/workspaces/runtime-renderer.js";
|
||||
import { parseWorkspaceYaml } from "../src/workspaces/schema.js";
|
||||
|
||||
@@ -56,6 +57,7 @@ diagnostics:
|
||||
method: POST
|
||||
path: /vector/diagnostic-probe
|
||||
auth: bearer
|
||||
response: { operation: operation }
|
||||
`);
|
||||
|
||||
const writerWorkspace = parseWorkspaceYaml(`workspace:
|
||||
@@ -88,6 +90,11 @@ semantic_index:
|
||||
llm_policy:
|
||||
allowed: [zai/glm-5.2]
|
||||
diagnostics:
|
||||
dwh_rest:
|
||||
method: POST
|
||||
path: /rpc/ping
|
||||
auth: bearer
|
||||
response: { database: database, schema: schema }
|
||||
vector_rest:
|
||||
metadata:
|
||||
method: GET
|
||||
@@ -98,6 +105,7 @@ diagnostics:
|
||||
method: POST
|
||||
path: /vector/diagnostic-probe
|
||||
auth: bearer
|
||||
response: { operation: operation }
|
||||
`);
|
||||
|
||||
const bindings: RuntimeBindings = {
|
||||
@@ -123,6 +131,7 @@ const bindings: RuntimeBindings = {
|
||||
THT_WS_PSD_CLINICAL_VECTOR_TLS_CA_FILE: "/run/secrets/vector-ca",
|
||||
},
|
||||
},
|
||||
vectorWriter: { transport: "rest_api", missing: [], values: {} },
|
||||
embedding: {
|
||||
transport: "rest_api",
|
||||
missing: [],
|
||||
@@ -142,9 +151,13 @@ const writerBindings: RuntimeBindings = {
|
||||
values: {
|
||||
THT_WS_PSD_CLINICAL_VECTOR_BASE_URL: "https://vector.example.test",
|
||||
THT_WS_PSD_CLINICAL_VECTOR_API_KEY_FILE: "/run/secrets/vector-reader-key",
|
||||
THT_WS_PSD_CLINICAL_VECTOR_WRITER_API_KEY_FILE: "/run/secrets/vector-writer-key",
|
||||
},
|
||||
},
|
||||
vectorWriter: {
|
||||
transport: "rest_api",
|
||||
missing: [],
|
||||
values: { THT_WS_PSD_CLINICAL_VECTOR_WRITER_API_KEY_FILE: "/run/secrets/vector-writer-key" },
|
||||
},
|
||||
};
|
||||
|
||||
function successfulAdapters(overrides: Partial<DiagnosticAdapters> = {}): DiagnosticAdapters {
|
||||
@@ -448,6 +461,40 @@ test("requires a matching embedding model vector and removes its unique write pr
|
||||
}));
|
||||
});
|
||||
|
||||
test("passes the resolver's distinct vector-writer binding to the diagnoser", async () => {
|
||||
const directory = await mkdtemp(join(tmpdir(), "thothii-diagnostic-bindings-"));
|
||||
const readerKey = join(directory, "reader-key");
|
||||
const writerKey = join(directory, "writer-key");
|
||||
const dwhKey = join(directory, "dwh-key");
|
||||
await Promise.all([
|
||||
writeFile(readerKey, "reader\n", { mode: 0o600 }),
|
||||
writeFile(writerKey, "writer\n", { mode: 0o600 }),
|
||||
writeFile(dwhKey, "dwh\n", { mode: 0o600 }),
|
||||
]);
|
||||
const adapters = successfulAdapters();
|
||||
try {
|
||||
const resolved = resolveRuntimeBindings(writerWorkspace, {
|
||||
THT_WS_PSD_CLINICAL_DWH_TRANSPORT: "rest_api",
|
||||
THT_WS_PSD_CLINICAL_DWH_BASE_URL: "https://dwh.example.test",
|
||||
THT_WS_PSD_CLINICAL_DWH_API_KEY_FILE: dwhKey,
|
||||
THT_WS_PSD_CLINICAL_VECTOR_TRANSPORT: "rest_api",
|
||||
THT_WS_PSD_CLINICAL_VECTOR_BASE_URL: "https://vector.example.test",
|
||||
THT_WS_PSD_CLINICAL_VECTOR_API_KEY_FILE: readerKey,
|
||||
THT_WS_PSD_CLINICAL_VECTOR_WRITER_API_KEY_FILE: writerKey,
|
||||
THT_WS_PSD_CLINICAL_EMBEDDING_BASE_URL: "https://embedding.example.test",
|
||||
}, [directory]);
|
||||
|
||||
await diagnose(adapters)(writerWorkspace, resolved, { writeProbe: true });
|
||||
|
||||
expect(resolved.vectorWriter.values).toEqual({
|
||||
THT_WS_PSD_CLINICAL_VECTOR_WRITER_API_KEY_FILE: writerKey,
|
||||
});
|
||||
expect(adapters.writeDiagnosticRecord).toHaveBeenCalledWith(expect.objectContaining({ credentialFile: writerKey }));
|
||||
} finally {
|
||||
await rm(directory, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("keeps a reader-only workspace activatable without a vector write probe", async () => {
|
||||
const adapters = successfulAdapters();
|
||||
|
||||
@@ -476,11 +523,8 @@ test("rejects a writer credential that aliases the reader credential", async ()
|
||||
const adapters = successfulAdapters();
|
||||
const aliasedBindings: RuntimeBindings = {
|
||||
...writerBindings,
|
||||
vector: { ...writerBindings.vector, values: {
|
||||
...writerBindings.vector.values,
|
||||
THT_WS_PSD_CLINICAL_VECTOR_API_KEY_FILE: readerKey,
|
||||
THT_WS_PSD_CLINICAL_VECTOR_WRITER_API_KEY_FILE: writerAlias,
|
||||
} },
|
||||
vector: { ...writerBindings.vector, values: { ...writerBindings.vector.values, THT_WS_PSD_CLINICAL_VECTOR_API_KEY_FILE: readerKey } },
|
||||
vectorWriter: { ...writerBindings.vectorWriter, values: { THT_WS_PSD_CLINICAL_VECTOR_WRITER_API_KEY_FILE: writerAlias } },
|
||||
};
|
||||
|
||||
try {
|
||||
@@ -555,6 +599,29 @@ test("requires an authenticated TLS database query before direct diagnostics suc
|
||||
}
|
||||
});
|
||||
|
||||
test("uses system trust for direct and SSH PostgreSQL diagnostics when no CA binding exists", async () => {
|
||||
const directory = await mkdtemp(join(tmpdir(), "thothii-diagnostic-"));
|
||||
const passwordFile = join(directory, "password");
|
||||
await writeFile(passwordFile, "password\n", { mode: 0o600 });
|
||||
const query = vi.fn(async () => ({ rows: [{ database: "warehouse", schema: "datawarehouse" }] }));
|
||||
const connect = vi.fn(async () => ({ query, end: vi.fn(async () => undefined) }));
|
||||
const adapter = createConcreteDiagnosticAdapters({ databaseClient: { connect } } as any);
|
||||
try {
|
||||
for (const transport of ["postgres_direct", "ssh_tunnel"] as const) {
|
||||
await expect(adapter.probeConnector({
|
||||
role: "dwh", transport, host: "127.0.0.1", port: 5432, user: "reader", credentialFile: passwordFile,
|
||||
resource: { database: "warehouse", schema: "datawarehouse" }, timeoutMs: 5000,
|
||||
signal: new AbortController().signal,
|
||||
})).resolves.toMatchObject({ tlsVerified: true, authenticated: true });
|
||||
}
|
||||
expect(connect).toHaveBeenCalledTimes(2);
|
||||
expect(connect).toHaveBeenNthCalledWith(1, expect.objectContaining({ tlsCaFile: undefined }));
|
||||
expect(connect).toHaveBeenNthCalledWith(2, expect.objectContaining({ tlsCaFile: undefined }));
|
||||
} finally {
|
||||
await rm(directory, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("selects the vector index containing the declared vector column for direct metadata", async () => {
|
||||
const directory = await mkdtemp(join(tmpdir(), "thothii-diagnostic-"));
|
||||
const passwordFile = join(directory, "password");
|
||||
@@ -597,20 +664,41 @@ test("applies declared auth modes and rejects private CA files across vector RES
|
||||
const keyFile = join(directory, "api-key");
|
||||
const caFile = join(directory, "ca.pem");
|
||||
await Promise.all([writeFile(keyFile, "writer-key\n", { mode: 0o600 }), writeFile(caFile, "private-ca\n")]);
|
||||
const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ collection: "clinical_documents", dimensions: 768, distance: "cosine", model: "embed" }), { status: 200, headers: { "content-type": "application/json" } }));
|
||||
const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ collection: "clinical_documents", dimensions: 768, distance: "cosine", model: "embed", operation: "create" }), { status: 200, headers: { "content-type": "application/json" } }));
|
||||
vi.stubGlobal("fetch", fetchSpy);
|
||||
const adapter = createConcreteDiagnosticAdapters();
|
||||
const signal = new AbortController().signal;
|
||||
try {
|
||||
await adapter.inspectVector({ transport: "rest_api", baseUrl: "https://vector.example.test", collection: "clinical_documents", timeoutMs: 1, signal, diagnostic: { method: "GET", path: "/metadata", auth: "none", response: { collection: "collection", dimensions: "dimensions", distance: "distance" } } });
|
||||
await adapter.probeEmbedding({ baseUrl: "https://embed.example.test", model: "embed", timeoutMs: 1, signal, credentialFile: keyFile, diagnostic: { method: "POST", path: "/embed", auth: "x-api-key", response: { model: "model", dimensions: "dimensions" } } });
|
||||
await adapter.writeDiagnosticRecord({ baseUrl: "https://vector.example.test", credentialFile: keyFile, collection: "clinical_documents", dimensions: 768, id: "diagnostic:test", timeoutMs: 1, signal, diagnostic: { method: "POST", path: "/probe", auth: "none" } });
|
||||
expect(fetchSpy.mock.calls[0]?.[1]).toMatchObject({ headers: {} });
|
||||
expect(fetchSpy.mock.calls[1]?.[1]).toMatchObject({ headers: { "x-api-key": "writer-key" } });
|
||||
expect(fetchSpy.mock.calls[2]?.[1]).toMatchObject({ headers: expect.not.objectContaining({ authorization: expect.anything() }) });
|
||||
await expect(adapter.inspectVector({ transport: "rest_api", baseUrl: "https://vector.example.test", credentialFile: keyFile, tlsCaFile: caFile, collection: "clinical_documents", timeoutMs: 1, signal, diagnostic: { method: "GET", path: "/metadata", auth: "bearer", response: { collection: "collection", dimensions: "dimensions", distance: "distance" } } })).rejects.toThrow("vector metadata adapter is unavailable");
|
||||
await expect(adapter.probeEmbedding({ baseUrl: "https://embed.example.test", credentialFile: keyFile, tlsCaFile: caFile, model: "embed", timeoutMs: 1, signal, diagnostic: { method: "POST", path: "/embed", auth: "bearer", response: { model: "model", dimensions: "dimensions" } } })).rejects.toThrow("embedding probe failed");
|
||||
await expect(adapter.removeDiagnosticRecord({ baseUrl: "https://vector.example.test", credentialFile: keyFile, tlsCaFile: caFile, collection: "clinical_documents", id: "diagnostic:test", dimensions: 768, timeoutMs: 1, signal, diagnostic: { method: "POST", path: "/probe", auth: "bearer" } })).rejects.toThrow("vector write adapter is unavailable");
|
||||
await expect(adapter.removeDiagnosticRecord({ baseUrl: "https://vector.example.test", credentialFile: keyFile, tlsCaFile: caFile, collection: "clinical_documents", id: "diagnostic:test", dimensions: 768, timeoutMs: 1, signal, diagnostic: { method: "POST", path: "/probe", auth: "bearer", response: { operation: "operation" } } })).rejects.toThrow("vector write adapter is unavailable");
|
||||
} finally {
|
||||
vi.unstubAllGlobals();
|
||||
await rm(directory, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("validates that the reversible writer response confirms each requested operation", async () => {
|
||||
const directory = await mkdtemp(join(tmpdir(), "thothii-diagnostic-"));
|
||||
const keyFile = join(directory, "writer-key");
|
||||
await writeFile(keyFile, "writer\n", { mode: 0o600 });
|
||||
const fetchSpy = vi.fn(async (_url: string, init: RequestInit) => new Response(JSON.stringify({
|
||||
operation: JSON.parse(String(init.body)).operation === "create" ? "create" : "not-removed",
|
||||
}), { status: 200, headers: { "content-type": "application/json" } }));
|
||||
vi.stubGlobal("fetch", fetchSpy);
|
||||
const request = {
|
||||
baseUrl: "https://vector.example.test", credentialFile: keyFile, collection: "clinical_documents",
|
||||
dimensions: 768, id: "diagnostic:test", timeoutMs: 5000, signal: new AbortController().signal,
|
||||
diagnostic: { method: "POST" as const, path: "/probe", auth: "bearer" as const, response: { operation: "operation" } },
|
||||
};
|
||||
try {
|
||||
const adapter = createConcreteDiagnosticAdapters();
|
||||
await expect(adapter.writeDiagnosticRecord(request)).resolves.toBeUndefined();
|
||||
await expect(adapter.removeDiagnosticRecord(request)).rejects.toThrow("vector write adapter is unavailable");
|
||||
} finally {
|
||||
vi.unstubAllGlobals();
|
||||
await rm(directory, { recursive: true, force: true });
|
||||
|
||||
Reference in New Issue
Block a user