Publish documentation / publish (push) Successful in 1m27s
Add PostgreSQL-backed memory, editable evidence with source review and activation, and human-approved archive repairs across the harness, API, and UI. Include migrations, deployment support, regression coverage, and validation documentation. Refresh permissions from validated session roles so existing administrator logins can access newly deployed archive management features.
426 lines
13 KiB
TypeScript
426 lines
13 KiB
TypeScript
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { afterEach, expect, test } from "vitest";
|
|
import { parse } from "yaml";
|
|
import {
|
|
renderRuntimeConfig,
|
|
type RuntimeBindings,
|
|
type RuntimePaths,
|
|
type SemanticRuntimeConfig,
|
|
} from "../src/workspaces/runtime-renderer.js";
|
|
import { supportsSessionRuntime } from "../src/workspaces/bindings.js";
|
|
import { parseRuntimeWorkspaceYaml } from "../src/workspaces/schema.js";
|
|
|
|
const workspaceV4 = parseRuntimeWorkspaceYaml(`workspace:
|
|
schema_version: 4
|
|
id: psd-clinical
|
|
name: Policlinico San Donato
|
|
language: it
|
|
dwh:
|
|
engine: postgres
|
|
database: postgres
|
|
schema: datawarehouse
|
|
supported_transports: [postgres_direct, rest_api, ssh_tunnel]
|
|
`);
|
|
const paths: RuntimePaths = {
|
|
sessions: "/data/workspaces/psd-clinical/sessions",
|
|
artifacts: "/data/workspaces/psd-clinical/artifacts",
|
|
indexes: "/data/workspaces/psd-clinical/indexes",
|
|
memory: "/data/workspaces/psd-clinical/memory",
|
|
};
|
|
const semanticRuntime: SemanticRuntimeConfig = {
|
|
internalQdrantUrl: "http://qdrant:6333",
|
|
internalEmbeddingUrl: "http://embedding:11434",
|
|
internalEmbeddingId: "ollama/qwen3-embedding:0.6b",
|
|
internalEmbeddingModel: "qwen3-embedding:0.6b",
|
|
internalEmbeddingDimensions: 1024,
|
|
};
|
|
const directBindings: RuntimeBindings = {
|
|
dwh: {
|
|
transport: "postgres_direct",
|
|
missing: [],
|
|
values: {
|
|
THT_WS_PSD_CLINICAL_DWH_HOST: "dwh.internal",
|
|
THT_WS_PSD_CLINICAL_DWH_PORT: "5432",
|
|
THT_WS_PSD_CLINICAL_DWH_USER: "thoth_reader",
|
|
THT_WS_PSD_CLINICAL_DWH_PASSWORD_FILE: "/run/secrets/dwh-password",
|
|
THT_WS_PSD_CLINICAL_DWH_TLS_CA_FILE: "/run/secrets/dwh-ca.pem",
|
|
},
|
|
},
|
|
evidence: { missing: [], values: {} },
|
|
};
|
|
|
|
test("derives the internal Qdrant and Ollama runtime shape from workspace v4 plus installation config", () => {
|
|
const rendered = parse(renderRuntimeConfig(workspaceV4, directBindings, paths, {
|
|
workspaceId: "psd-clinical", workspaceRevision: "a".repeat(40),
|
|
}, {}, semanticRuntime));
|
|
|
|
expect(rendered).toMatchObject({
|
|
runtime_identity: {
|
|
workspace_id: "psd-clinical",
|
|
workspace_revision: "a".repeat(40),
|
|
source_identity: "workspace://psd-clinical",
|
|
},
|
|
language: "it",
|
|
database: {
|
|
host: "dwh.internal", port: 5432, database: "postgres", schema: "datawarehouse",
|
|
user: "thoth_reader", password_file: "/run/secrets/dwh-password",
|
|
ssl_ca_file: "/run/secrets/dwh-ca.pem", transport: "direct",
|
|
},
|
|
dwh: { type: "postgres_direct" },
|
|
resources: {
|
|
vector: {
|
|
engine: "qdrant",
|
|
base_url: "http://qdrant:6333",
|
|
collections: {
|
|
reference: "psd-clinical-reference",
|
|
memory: "psd-clinical-memory",
|
|
},
|
|
},
|
|
embeddings: {
|
|
provider: "ollama_internal", base_url: "http://embedding:11434",
|
|
id: "ollama/qwen3-embedding:0.6b",
|
|
model: "qwen3-embedding:0.6b", dimensions: 1024,
|
|
},
|
|
},
|
|
paths,
|
|
});
|
|
expect(rendered).not.toHaveProperty("vector_db");
|
|
expect(rendered).not.toHaveProperty("embeddings");
|
|
expect(rendered).not.toHaveProperty("vector_rest");
|
|
});
|
|
|
|
test("renders workspace-v4 DWH REST without exposing secret contents", () => {
|
|
const rendered = parse(renderRuntimeConfig(workspaceV4, {
|
|
dwh: {
|
|
transport: "rest_api", missing: [], values: {
|
|
THT_WS_PSD_CLINICAL_DWH_BASE_URL: "https://dwh.example.test",
|
|
THT_WS_PSD_CLINICAL_DWH_API_KEY_FILE: "/run/secrets/dwh-api-key",
|
|
},
|
|
},
|
|
evidence: { missing: [], values: {} },
|
|
}, paths));
|
|
|
|
expect(rendered.rest).toEqual({
|
|
base_url: "https://dwh.example.test", api_key_file: "/run/secrets/dwh-api-key",
|
|
});
|
|
expect(rendered.dwh).toMatchObject({
|
|
type: "thoth_rest", database: { database: "postgres", schema: "datawarehouse" },
|
|
});
|
|
expect(JSON.stringify(rendered)).not.toContain("api_key:");
|
|
});
|
|
|
|
test("runtime support is fail-closed for DWH SSH and incomplete Evidence", () => {
|
|
expect(supportsSessionRuntime(directBindings)).toBe(true);
|
|
expect(supportsSessionRuntime({
|
|
...directBindings, dwh: { ...directBindings.dwh, transport: "ssh_tunnel" },
|
|
})).toBe(false);
|
|
expect(supportsSessionRuntime({
|
|
...directBindings, evidence: { values: {}, missing: ["EVIDENCE_FILE"] },
|
|
})).toBe(false);
|
|
});
|
|
|
|
const evidenceSecretRoots: string[] = [];
|
|
|
|
afterEach(() => {
|
|
evidenceSecretRoots.splice(0).forEach((root) => rmSync(root, { recursive: true, force: true }));
|
|
});
|
|
|
|
function evidenceSecretFile(name: string, contents: string): string {
|
|
const root = mkdtempSync(join(tmpdir(), "tht-renderer-evidence-secret-"));
|
|
evidenceSecretRoots.push(root);
|
|
const path = join(root, name);
|
|
writeFileSync(path, contents, { mode: 0o600 });
|
|
return path;
|
|
}
|
|
|
|
function evidenceWorkspace(
|
|
source: Record<string, unknown>,
|
|
policy?: Record<string, unknown>,
|
|
evidenceSchemaVersion?: number,
|
|
) {
|
|
return parseRuntimeWorkspaceYaml(`${canonicalEvidenceWorkspace}\nevidence:${
|
|
evidenceSchemaVersion === undefined ? "" : `\n schema_version: ${evidenceSchemaVersion}`
|
|
}\n source: ${JSON.stringify(source)}${
|
|
policy === undefined ? "" : `\n policy: ${JSON.stringify(policy)}`
|
|
}\n`);
|
|
}
|
|
|
|
const canonicalEvidenceWorkspace = `workspace:
|
|
schema_version: 4
|
|
id: psd-clinical
|
|
name: Runtime Evidence
|
|
language: en
|
|
dwh:
|
|
engine: postgres
|
|
database: analytics
|
|
schema: mart
|
|
supported_transports: [postgres_direct]
|
|
`;
|
|
|
|
const evidenceRevision = "1".repeat(40);
|
|
const evidenceContext = {
|
|
workspaceId: "psd-clinical",
|
|
workspaceRevision: evidenceRevision,
|
|
revisionContentRoot: `/srv/registry/snapshots/${evidenceRevision}`,
|
|
};
|
|
|
|
function evidenceRender(
|
|
source: Record<string, unknown>,
|
|
evidenceBinding: RuntimeBindings["evidence"] = { missing: [], values: {} },
|
|
policy?: Record<string, unknown>,
|
|
evidenceSchemaVersion?: number,
|
|
) {
|
|
return renderRuntimeConfig(
|
|
evidenceWorkspace(source, policy, evidenceSchemaVersion),
|
|
{ ...directBindings, evidence: evidenceBinding },
|
|
paths,
|
|
evidenceContext,
|
|
{},
|
|
semanticRuntime,
|
|
);
|
|
}
|
|
|
|
test("renders filesystem Evidence below the immutable revision content root with default policy", () => {
|
|
const yaml = evidenceRender({
|
|
type: "filesystem",
|
|
uri: "psd-clinical/evidence",
|
|
}, undefined, undefined, 2);
|
|
const rendered = parse(yaml);
|
|
|
|
expect(rendered.runtime_identity.workspace_revision).toBe(evidenceRevision);
|
|
expect(rendered.evidence).toEqual({
|
|
schema_version: 2,
|
|
local_archive_root: "/srv/registry/repo/psd-clinical",
|
|
sources: [{
|
|
type: "filesystem",
|
|
root: `/srv/registry/snapshots/${evidenceRevision}/psd-clinical/evidence`,
|
|
patterns: ["curated/**/*.md"],
|
|
max_bytes: 10_485_760,
|
|
}],
|
|
});
|
|
expect(rendered.vector).toEqual({
|
|
max_chunk_chars: 4_000,
|
|
retain_published_generations: 3,
|
|
});
|
|
expect(rendered.evidence.sources[0].root).not.toContain("/srv/registry/repo");
|
|
});
|
|
|
|
test("renders public HTTP Evidence with exact fractional-second timeouts and every policy limit", () => {
|
|
const rendered = parse(evidenceRender({
|
|
type: "http",
|
|
uris: ["https://evidence.example.test/guide.md"],
|
|
authentication: "none",
|
|
connect_timeout_ms: 1_001,
|
|
read_timeout_ms: 30_001,
|
|
max_bytes: 12_345,
|
|
max_redirects: 0,
|
|
allow_private_hosts: true,
|
|
max_cache_bytes: 67_890,
|
|
}, undefined, {
|
|
max_chunk_chars: 2_501,
|
|
retain_published_generations: 7,
|
|
}));
|
|
|
|
expect(rendered.evidence).toEqual({
|
|
local_archive_root: "/srv/registry/repo/psd-clinical",
|
|
sources: [{
|
|
type: "http",
|
|
urls: ["https://evidence.example.test/guide.md"],
|
|
connect_timeout: 1.001,
|
|
read_timeout: 30.001,
|
|
max_bytes: 12_345,
|
|
max_redirects: 0,
|
|
allow_private_hosts: true,
|
|
max_cache_bytes: 67_890,
|
|
}],
|
|
});
|
|
expect(rendered.vector).toEqual({
|
|
max_chunk_chars: 2_501,
|
|
retain_published_generations: 7,
|
|
});
|
|
});
|
|
|
|
test("renders signed HTTP Evidence as provenance plus a validated file path only", () => {
|
|
const canary = "SIGNED-URL-CANARY-CONTENT";
|
|
const signedFile = evidenceSecretFile("evidence-signed-urls.json", canary);
|
|
const yaml = evidenceRender({
|
|
type: "http",
|
|
uris: [
|
|
"https://evidence.example.test/guide.md",
|
|
"https://evidence.example.test/runbook.md",
|
|
],
|
|
authentication: "signed_urls_file",
|
|
}, {
|
|
missing: [],
|
|
values: { THT_WS_PSD_CLINICAL_EVIDENCE_SIGNED_URLS_FILE: signedFile },
|
|
});
|
|
|
|
expect(parse(yaml).evidence.sources).toEqual([{
|
|
type: "http",
|
|
provenance_urls: [
|
|
"https://evidence.example.test/guide.md",
|
|
"https://evidence.example.test/runbook.md",
|
|
],
|
|
signed_urls_file: signedFile,
|
|
connect_timeout: 5,
|
|
read_timeout: 30,
|
|
max_bytes: 10_485_760,
|
|
max_redirects: 5,
|
|
allow_private_hosts: false,
|
|
max_cache_bytes: 67_108_864,
|
|
}]);
|
|
expect(yaml).not.toContain(canary);
|
|
});
|
|
|
|
test("renders ambient S3 Evidence without credential keys", () => {
|
|
const rendered = parse(evidenceRender({
|
|
type: "s3",
|
|
uri: "s3://clinical-evidence/published/guides/",
|
|
credentials: "ambient",
|
|
region: "eu-west-1",
|
|
}));
|
|
|
|
expect(rendered.evidence.sources).toEqual([{
|
|
type: "s3",
|
|
bucket: "clinical-evidence",
|
|
prefix: "published/guides/",
|
|
region: "eu-west-1",
|
|
trusted_endpoint: false,
|
|
allow_private_endpoint: false,
|
|
allow_insecure_endpoint: false,
|
|
max_bytes: 10_485_760,
|
|
max_objects: 10_000,
|
|
max_pages: 100,
|
|
page_size: 1_000,
|
|
}]);
|
|
expect(JSON.stringify(rendered.evidence)).not.toMatch(/access_key|secret_key|session_token/);
|
|
});
|
|
|
|
test("renders static S3 Evidence with endpoint policy, limits, and file paths but no contents", () => {
|
|
const accessCanary = "ACCESS-CANARY-CONTENT";
|
|
const secretCanary = "SECRET-CANARY-CONTENT";
|
|
const tokenCanary = "TOKEN-CANARY-CONTENT";
|
|
const accessFile = evidenceSecretFile("evidence-access", accessCanary);
|
|
const secretFile = evidenceSecretFile("evidence-secret", secretCanary);
|
|
const tokenFile = evidenceSecretFile("evidence-token", tokenCanary);
|
|
const source = {
|
|
type: "s3",
|
|
uri: "s3://clinical-evidence/published/",
|
|
credentials: "static_files",
|
|
endpoint_url: "http://minio.internal:9000/",
|
|
region: "eu-central-1",
|
|
trusted_endpoint: true,
|
|
allow_private_endpoint: true,
|
|
allow_insecure_endpoint: true,
|
|
max_bytes: 222,
|
|
max_objects: 33,
|
|
max_pages: 4,
|
|
page_size: 5,
|
|
};
|
|
const values = {
|
|
THT_WS_PSD_CLINICAL_EVIDENCE_ACCESS_KEY_FILE: accessFile,
|
|
THT_WS_PSD_CLINICAL_EVIDENCE_SECRET_KEY_FILE: secretFile,
|
|
THT_WS_PSD_CLINICAL_EVIDENCE_SESSION_TOKEN_FILE: tokenFile,
|
|
};
|
|
const yaml = evidenceRender(source, { missing: [], values });
|
|
|
|
expect(parse(yaml).evidence.sources).toEqual([{
|
|
type: "s3",
|
|
bucket: "clinical-evidence",
|
|
prefix: "published/",
|
|
endpoint_url: "http://minio.internal:9000/",
|
|
region: "eu-central-1",
|
|
access_key_file: accessFile,
|
|
secret_key_file: secretFile,
|
|
session_token_file: tokenFile,
|
|
trusted_endpoint: true,
|
|
allow_private_endpoint: true,
|
|
allow_insecure_endpoint: true,
|
|
max_bytes: 222,
|
|
max_objects: 33,
|
|
max_pages: 4,
|
|
page_size: 5,
|
|
}]);
|
|
expect(yaml).not.toContain(accessCanary);
|
|
expect(yaml).not.toContain(secretCanary);
|
|
expect(yaml).not.toContain(tokenCanary);
|
|
|
|
const withoutToken = parse(evidenceRender(source, {
|
|
missing: [],
|
|
values: {
|
|
THT_WS_PSD_CLINICAL_EVIDENCE_ACCESS_KEY_FILE: accessFile,
|
|
THT_WS_PSD_CLINICAL_EVIDENCE_SECRET_KEY_FILE: secretFile,
|
|
},
|
|
})).evidence.sources[0];
|
|
expect(withoutToken).toMatchObject({ access_key_file: accessFile, secret_key_file: secretFile });
|
|
expect(withoutToken).not.toHaveProperty("session_token_file");
|
|
});
|
|
|
|
test("omits Evidence configuration and policy when the descriptor has no Evidence", () => {
|
|
const rendered = parse(renderRuntimeConfig(
|
|
workspaceV4,
|
|
directBindings,
|
|
paths,
|
|
evidenceContext,
|
|
{},
|
|
semanticRuntime,
|
|
));
|
|
|
|
expect(rendered).not.toHaveProperty("evidence");
|
|
expect(rendered).not.toHaveProperty("vector");
|
|
});
|
|
|
|
test.each([
|
|
{
|
|
source: {
|
|
type: "http", uris: ["https://evidence.example.test/guide.md"],
|
|
authentication: "signed_urls_file",
|
|
},
|
|
missing: "THT_WS_PSD_CLINICAL_EVIDENCE_SIGNED_URLS_FILE",
|
|
},
|
|
{
|
|
source: {
|
|
type: "s3", uri: "s3://clinical-evidence/published/", credentials: "static_files",
|
|
},
|
|
missing: "THT_WS_PSD_CLINICAL_EVIDENCE_SECRET_KEY_FILE",
|
|
},
|
|
])("rejects missing required Evidence binding $missing before rendering", ({ source, missing }) => {
|
|
expect(() => evidenceRender(source, { missing: [missing], values: {} })).toThrow(
|
|
"runtime configuration requires complete Evidence bindings",
|
|
);
|
|
});
|
|
|
|
test("is byte deterministic and revision-bound for descriptor-identical content-only commits", () => {
|
|
const source = {
|
|
type: "filesystem",
|
|
uri: "psd-clinical/evidence",
|
|
};
|
|
const first = evidenceRender(source);
|
|
expect(evidenceRender(source)).toBe(first);
|
|
|
|
const nextRevision = "2".repeat(40);
|
|
const next = renderRuntimeConfig(
|
|
evidenceWorkspace(source),
|
|
directBindings,
|
|
paths,
|
|
{
|
|
workspaceId: "psd-clinical",
|
|
workspaceRevision: nextRevision,
|
|
revisionContentRoot: `/srv/registry/snapshots/${nextRevision}`,
|
|
},
|
|
{},
|
|
semanticRuntime,
|
|
);
|
|
const firstParsed = parse(first);
|
|
const nextParsed = parse(next);
|
|
|
|
expect(next).not.toBe(first);
|
|
expect(nextParsed.runtime_identity.workspace_revision).toBe(nextRevision);
|
|
expect(nextParsed.evidence.sources[0].root).toBe(
|
|
`/srv/registry/snapshots/${nextRevision}/psd-clinical/evidence`,
|
|
);
|
|
expect(nextParsed.evidence.sources[0].root).not.toBe(firstParsed.evidence.sources[0].root);
|
|
});
|