import { constants, accessSync, readFileSync, realpathSync, statSync } from "node:fs"; import { basename, dirname, join } from "node:path"; import { createRequire } from "node:module"; import { resolveRuntimeBindings } from "../backend/src/workspaces/bindings.js"; import { renderRuntimeConfig } from "../backend/src/workspaces/runtime-renderer.js"; const requireFromBackend = createRequire(new URL("../backend/package.json", import.meta.url)); const { parse } = requireFromBackend("yaml") as { parse: (value: string) => any }; const [renderedPath, workspacePath, profile, bundleSource, runtimePasswordSourceInput] = process.argv.slice(2); if (!renderedPath || !workspacePath || (profile !== "local" && profile !== "server") || !bundleSource || !runtimePasswordSourceInput) { throw new Error( "usage: task13-runtime-fixture-check RENDERED_JSON WORKSPACE_YAML local|server BUNDLE PASSWORD", ); } const config = JSON.parse(readFileSync(renderedPath, "utf8")); const workspace = parse(readFileSync(workspacePath, "utf8")); const core = config.services?.core; const frontend = config.services?.frontend; if (!core || !frontend) throw new Error("fixture render must contain core and frontend"); const qdrant = config.services?.qdrant; const embedding = config.services?.embedding; const modelInit = config.services?.["embedding-model-init"]; if (!qdrant || !embedding || !modelInit) { throw new Error("fixture render must contain the private semantic services"); } for (const [name, service, expectedExpose] of [ ["qdrant", qdrant, "6333"], ["embedding", embedding, "11434"], ] as const) { const localQdrantDashboard = name === "qdrant" && profile === "local" && (service.ports || []).length === 1 && service.ports[0].host_ip === "127.0.0.1" && Number(service.ports[0].target) === 6333; if ((service.ports || []).length !== 0 && !localQdrantDashboard) { throw new Error(`${name} must not publish host ports outside the local Qdrant dashboard`); } if ((service.expose || []).join(",") !== expectedExpose) { throw new Error(`${name} must expose only ${expectedExpose}`); } } if ((modelInit.ports || []).length !== 0) { throw new Error("embedding-model-init must not publish host ports"); } const expected = { THT_WS_TASK13_SMOKE_DWH_TRANSPORT: "postgres_direct", THT_WS_TASK13_SMOKE_DWH_HOST: "dwh.task13.invalid", THT_WS_TASK13_SMOKE_DWH_PORT: "5432", THT_WS_TASK13_SMOKE_DWH_USER: "task13_reader", THT_WS_TASK13_SMOKE_DWH_PASSWORD_FILE: "/run/secrets/task13-runtime-password", }; for (const [name, value] of Object.entries(expected)) { if (core.environment?.[name] !== value) { throw new Error(`core runtime binding ${name} is ${JSON.stringify(core.environment?.[name])}, want ${JSON.stringify(value)}`); } if (Object.hasOwn(frontend.environment || {}, name)) { throw new Error(`runtime binding escaped to frontend: ${name}`); } } const semanticRuntime = { THT_INTERNAL_QDRANT_URL: "http://qdrant:6333", THT_INTERNAL_EMBEDDING_URL: "http://embedding:11434", THT_INTERNAL_EMBEDDING_MODEL: "qwen3-embedding:0.6b", THT_INTERNAL_EMBEDDING_DIMENSIONS: "1024", }; for (const [name, value] of Object.entries(semanticRuntime)) { if (core.environment?.[name] !== value) { throw new Error(`core semantic runtime ${name} is ${JSON.stringify(core.environment?.[name])}, want ${JSON.stringify(value)}`); } if (Object.hasOwn(frontend.environment || {}, name)) { throw new Error(`semantic runtime escaped to frontend: ${name}`); } } for (const name of [ ["THT", "VEC", "REST", "URL"].join("_"), ["THT", "VEC", "WRITE", "REST", "URL"].join("_"), ["THT", "OLLAMA", "URL"].join("_"), ]) { if (Object.hasOwn(core.environment || {}, name) && core.environment?.[name] !== "") { throw new Error(`fixture render reintroduced external semantic binding ${name}`); } } if (workspace.workspace?.id !== "task13-smoke") throw new Error("fixture workspace id changed"); if (workspace.workspace?.schema_version !== 4) throw new Error("fixture workspace must use schema v4"); for (const forbidden of ["semantic_index", "llm_policy"]) { if (Object.hasOwn(workspace, forbidden)) { throw new Error(`fixture workspace must not own installation model configuration: ${forbidden}`); } } if (!statSync(bundleSource).isFile()) { throw new Error("fixture secret bundle source is not a regular file"); } accessSync(bundleSource, constants.R_OK); const coreBundle = (core.secrets || []).filter( (secret: any) => secret.source === "thothii_secrets" && secret.target === "thothii.secrets", ); if (profile === "local") { if (coreBundle.length !== 0) throw new Error("local core retained the host-owned secret bundle mount"); } else if (coreBundle.length !== 1) { throw new Error("server core lacks exactly one runtime secret bundle mount"); } if ((frontend.secrets || []).length !== 0) throw new Error("frontend received a runtime secret"); const mounts = core.volumes || []; const runtimePasswordMounts = mounts.filter( (mount: any) => mount.target === "/run/secrets/task13-runtime-password", ); if (profile === "local") { const projected = mounts.filter((mount: any) => mount.target === "/run/secrets"); if (runtimePasswordMounts.length !== 0 || projected.length !== 1 || projected[0].type !== "volume" || !projected[0].read_only || (projected[0].source !== "application-secrets" && !projected[0].source.endsWith("_application-secrets"))) { throw new Error("local secrets are not isolated in the Compose-owned projection volume"); } } else if (runtimePasswordMounts.length !== 1 || runtimePasswordMounts[0].type !== "bind" || !runtimePasswordMounts[0].read_only || !statSync(runtimePasswordMounts[0].source).isFile()) { throw new Error("server runtime fixture lacks one readable, read-only password-file bind"); } accessSync(runtimePasswordSourceInput, constants.R_OK); const generatedPiTargets = [ "/home/thoth/.pi/agent/models.json", "/home/thoth/.pi/agent/settings.json", ] as const; const piParent = mounts.filter((mount: any) => mount.target === "/home/thoth/.pi"); if (piParent.length !== 1) throw new Error("core lacks exactly one Pi state mount"); for (const target of generatedPiTargets) { const selected = mounts.filter((mount: any) => mount.target === target); if (selected.length !== 1 || selected[0].type !== "bind" || !selected[0].read_only) { throw new Error(`Pi fixture mount is not one generated read-only bind: ${target}`); } accessSync(selected[0].source, constants.R_OK); if (profile === "local") { if (piParent[0].type !== "volume") { throw new Error(`local Pi parent is not a state volume: ${target}`); } } else { const hidden = join(piParent[0].source, "agent", basename(target)); if (!statSync(hidden).isFile()) throw new Error(`server parent root lacks ${hidden}`); } } const authTarget = "/home/thoth/.pi/agent/auth.json"; const authMounts = mounts.filter((mount: any) => mount.target === authTarget); if (profile === "local") { if (authMounts.length !== 0) { throw new Error("local Pi auth must be projected into the state volume, not directly mounted"); } } else if (authMounts.length !== 1 || authMounts[0].type !== "bind" || !authMounts[0].read_only) { throw new Error("server Pi auth is not one independent read-only bind"); } for (const [target, localVolume] of [ ["/run/thothii-auth", "auth-runtime"], ["/fixtures/remote.git", "registry-remote"], ] as const) { const selected = mounts.filter((mount: any) => mount.target === target); if (selected.length !== 1 || !selected[0].read_only) { throw new Error(`core lacks exactly one read-only runtime mount: ${target}`); } if (profile === "local") { if (selected[0].type !== "volume" || (selected[0].source !== localVolume && !selected[0].source.endsWith(`_${localVolume}`))) { throw new Error(`local runtime fixture is not projected through ${localVolume}`); } } else if (selected[0].type !== "bind") { throw new Error(`server runtime fixture is not one read-only bind: ${target}`); } } const resolverEnvironment = { ...core.environment }; const runtimePasswordSource = realpathSync(runtimePasswordSourceInput); resolverEnvironment.THT_WS_TASK13_SMOKE_DWH_PASSWORD_FILE = runtimePasswordSource; const bindings = resolveRuntimeBindings(workspace, resolverEnvironment, [dirname(runtimePasswordSource)]); for (const [role, binding] of Object.entries(bindings)) { if ((binding as any).missing.length !== 0) { throw new Error(`workspace resolver reports missing ${role} bindings: ${(binding as any).missing.join(",")}`); } } const runtime = parse(renderRuntimeConfig(workspace, bindings, { sessions: "/data/sessions", artifacts: "/data/artifacts", indexes: "/data/indexes", }, { workspaceId: "task13-smoke", workspaceRevision: "task13-fixture", revisionContentRoot: join(dirname(workspacePath), "task13-fixture"), })); if (runtime.database.host !== expected.THT_WS_TASK13_SMOKE_DWH_HOST || runtime.database.user !== expected.THT_WS_TASK13_SMOKE_DWH_USER || runtime.database.password_file !== runtimePasswordSource) { throw new Error("workspace resolver produced the wrong DWH runtime"); } if (runtime.resources?.vector?.base_url !== "http://qdrant:6333" || runtime.resources?.vector?.collection !== "task13-smoke") { throw new Error("workspace resolver produced the wrong qdrant runtime"); } if (runtime.resources?.embeddings?.base_url !== "http://embedding:11434" || runtime.resources?.embeddings?.model !== "qwen3-embedding:0.6b" || runtime.resources?.embeddings?.dimensions !== 1024) { throw new Error("workspace resolver produced the wrong embedding runtime"); } const secret = readFileSync(bundleSource, "utf8").trim(); const runtimePassword = readFileSync(runtimePasswordSourceInput, "utf8"); if (JSON.stringify(config).includes(secret)) throw new Error("fixture render leaked application bundle content"); if (JSON.stringify(runtime).includes(secret)) throw new Error("runtime render leaked application bundle content"); if (JSON.stringify(config).includes(runtimePassword)) throw new Error("fixture render leaked runtime password content"); if (JSON.stringify(runtime).includes(runtimePassword)) throw new Error("runtime render leaked runtime password content");