import { expect, test } from "vitest"; import * as workspaceSchema from "../src/workspaces/schema.js"; import { parseWorkspaceYaml, serializeWorkspaceYaml, validateCanonicalWorkspace, type WorkspaceDescriptor, } from "../src/workspaces/schema.js"; export const validYaml = `workspace: schema_version: 3 id: psd-clinical name: Policlinico San Donato description: Clinical data warehouse workspace language: it dwh: engine: postgres database: postgres schema: datawarehouse port: 5432 timeout_ms: 5000 supported_transports: - postgres_direct - rest_api - ssh_tunnel semantic_index: vector_store: engine: qdrant collection: psd-clinical dimensions: 1024 distance: cosine embedding: provider: ollama_internal model: qwen3-embedding:0.6b dimensions: 1024 llm_policy: default: zai/glm-5.2 allowed: - zai/glm-5.2 - openai/gpt-5 `; test("rejects a workspace whose embedding dimensions differ from its collection", () => { expect(() => parseWorkspaceYaml(validYaml.replace("dimensions: 1024", "dimensions: 1536"))) .toThrow(/dimensions/i); }); test("rejects an LLM default outside its allowlist", () => { expect(() => parseWorkspaceYaml(validYaml.replace("- zai/glm-5.2", "- openai/gpt-5"))) .toThrow(/allowlist/i); }); test("rejects unknown keys and invalid immutable IDs", () => { expect(() => parseWorkspaceYaml(validYaml.replace(" language: it", " language: it\n label: PSD"))) .toThrow(/unrecognized key/i); expect(() => parseWorkspaceYaml(validYaml.replace("id: psd-clinical", "id: PSD"))) .toThrow(/id/i); }); test("rejects executable or otherwise custom YAML tags in canonical descriptors", () => { expect(() => parseWorkspaceYaml(validYaml.replace( "name: Policlinico San Donato", "name: !command echo-never-execute", ))).toThrow(/tag|yaml/i); }); test("accepts optional connection ports and timeouts but rejects unsafe values", () => { expect(parseWorkspaceYaml(validYaml).dwh.port).toBe(5432); expect(() => parseWorkspaceYaml(validYaml.replace("port: 5432", "port: 0"))) .toThrow(/port/i); expect(() => parseWorkspaceYaml(validYaml.replace("port: 5432", "port: 65536"))) .toThrow(/port/i); expect(() => parseWorkspaceYaml(validYaml.replace("timeout_ms: 5000", "timeout_ms: 0"))) .toThrow(/timeout/i); expect(() => parseWorkspaceYaml(validYaml.replace("dimensions: 1024", "dimensions: 2048"))) .toThrow(/1024|dimensions/i); }); test("accepts only the schema v3 internal qdrant semantic shape", () => { expect(parseWorkspaceYaml(validYaml)).toMatchObject({ workspace: { schema_version: 3, id: "psd-clinical" }, semantic_index: { vector_store: { engine: "qdrant", collection: "psd-clinical", dimensions: 1024, distance: "cosine", }, embedding: { provider: "ollama_internal", model: "qwen3-embedding:0.6b", dimensions: 1024, }, }, }); }); test("rejects pgvector semantic stores in schema v3", () => { expect(() => parseWorkspaceYaml(validYaml.replace("engine: qdrant", "engine: pgvector"))) .toThrow(/qdrant|pgvector/i); }); test("rejects supported_transports inside schema v3 semantic identity", () => { const withTransport = validYaml.replace( " distance: cosine\n", " distance: cosine\n supported_transports:\n - rest_api\n", ); expect(() => parseWorkspaceYaml(withTransport)).toThrow(/unrecognized key|supported_transports/i); }); test("rejects external embedding providers in schema v3", () => { expect(() => parseWorkspaceYaml(validYaml.replace("provider: ollama_internal", "provider: openai_compatible"))) .toThrow(/ollama_internal|provider/i); }); test("rejects non-cosine distance in schema v3", () => { expect(() => parseWorkspaceYaml(validYaml.replace("distance: cosine", "distance: l2"))) .toThrow(/cosine|distance/i); }); test("rejects unknown fields in schema v3 semantic identity", () => { const withUnknownField = validYaml.replace( " collection: psd-clinical\n", " collection: psd-clinical\n namespace: psd\n", ); expect(() => parseWorkspaceYaml(withUnknownField)).toThrow(/unrecognized key/i); }); test("rejects legacy semantic connector fields and diagnostics in schema v3", () => { expect(() => parseWorkspaceYaml(validYaml.replace( " collection: psd-clinical\n", " collection: psd-clinical\n database: postgres\n", ))).toThrow(/unrecognized key|database/i); expect(() => parseWorkspaceYaml(validYaml.replace( "llm_policy:\n", "diagnostics:\n vector_rest:\n metadata:\n method: GET\n path: /metadata\n auth: bearer\n response:\n collection: collection\n dimensions: dimensions\n distance: distance\nllm_policy:\n", ))).toThrow(/unrecognized key|vector_rest/i); }); test("keeps v1 and v2 descriptors parseable but non-operational", () => { const v1Yaml = `workspace: schema_version: 1 id: psd-clinical name: Policlinico San Donato language: it dwh: engine: postgres database: postgres schema: datawarehouse supported_transports: - postgres_direct semantic_index: vector_store: engine: pgvector collection: clinical_documents dimensions: 1024 distance: cosine supported_transports: - pgvector_direct embedding: provider: ollama_compatible model: nomic-embed-text-v2-moe dimensions: 1024 llm_policy: allowed: - zai/glm-5.2 `; const v2Yaml = `workspace: schema_version: 2 id: psd-clinical name: Policlinico San Donato language: it dwh: engine: postgres database: postgres schema: datawarehouse supported_transports: - postgres_direct semantic_index: vector_store: engine: pgvector database: postgres schema: vectors collection: clinical_documents dimensions: 1024 distance: cosine supported_transports: - pgvector_direct embedding: provider: ollama_compatible model: nomic-embed-text-v2-moe dimensions: 1024 llm_policy: allowed: - zai/glm-5.2 `; const v1 = parseWorkspaceYaml(v1Yaml); const v2 = parseWorkspaceYaml(v2Yaml); const isOperationalWorkspace = (workspaceSchema as { isOperationalWorkspace?: unknown }).isOperationalWorkspace; expect(v1.workspace.schema_version).toBe(1); expect(v2.workspace.schema_version).toBe(2); expect(validateCanonicalWorkspace(parseWorkspaceYaml(validYaml))).toMatchObject({ workspace: { schema_version: 3 }, }); expect(() => validateCanonicalWorkspace(v1)).toThrow(/schema version 3|migration/i); expect(() => validateCanonicalWorkspace(v2)).toThrow(/schema version 3|migration/i); expect(isOperationalWorkspace).toBeTypeOf("function"); expect((isOperationalWorkspace as (workspace: WorkspaceDescriptor) => boolean)(v1)).toBe(false); expect((isOperationalWorkspace as (workspace: WorkspaceDescriptor) => boolean)(v2)).toBe(false); }); test("constructs diagnostic URLs only when the resolved URL remains on the service origin", () => { const resolveDiagnosticUrl = (workspaceSchema as { resolveDiagnosticUrl?: unknown }).resolveDiagnosticUrl; expect(resolveDiagnosticUrl).toBeTypeOf("function"); expect((resolveDiagnosticUrl as (baseUrl: string, path: string) => URL)("https://service.example/base", "/rpc/ping")) .toMatchObject({ href: "https://service.example/rpc/ping" }); expect(() => (resolveDiagnosticUrl as (baseUrl: string, path: string) => URL)( "https://service.example/base", "//diagnostic.invalid/rpc", )).toThrow(/origin/i); }); test("rejects REST diagnostic declarations without their matching connector transport", () => { const diagnostics = `diagnostics: dwh_rest: method: POST path: /rpc/ping auth: bearer response: database: database schema: schema llm_policy: `; const declared = validYaml.replace("llm_policy:\n", diagnostics); expect(() => parseWorkspaceYaml(declared.replace(" - rest_api\n", ""))).toThrow(/dwh_rest/i); }); test("serializes canonical YAML that parses back to the same workspace", () => { const workspace = parseWorkspaceYaml(validYaml); const serialized = serializeWorkspaceYaml(workspace); expect(serializeWorkspaceYaml(parseWorkspaceYaml(serialized))).toBe(serialized); expect(parseWorkspaceYaml(serialized)).toEqual(workspace); });