Files
ThothII/scripts/task13-runtime-fixture-check.ts
T

108 lines
5.5 KiB
TypeScript

import { constants, accessSync, readFileSync, 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] = process.argv.slice(2);
if (!renderedPath || !workspacePath || (profile !== "local" && profile !== "server")) {
throw new Error("usage: task13-runtime-fixture-check RENDERED_JSON WORKSPACE_YAML local|server");
}
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 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 bundle = config.secrets?.thothii_secrets;
const bundleSource = bundle?.file;
if (typeof bundleSource !== "string" || !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 (coreBundle.length !== 1) throw new Error("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 (runtimePasswordMounts.length !== 1 || runtimePasswordMounts[0].type !== "bind"
|| !runtimePasswordMounts[0].read_only || !statSync(runtimePasswordMounts[0].source).isFile()) {
throw new Error("runtime fixture lacks one readable, read-only password-file bind");
}
accessSync(runtimePasswordMounts[0].source, constants.R_OK);
for (const target of [
"/home/thoth/.pi/agent/auth.json",
"/home/thoth/.pi/agent/models.json",
"/home/thoth/.pi/agent/settings.json",
]) {
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 read-only bind: ${target}`);
}
accessSync(selected[0].source, constants.R_OK);
if (profile === "server") {
const parent = mounts.find((mount: any) => mount.target === "/home/thoth/.pi");
const hidden = join(parent.source, "agent", basename(target));
if (!statSync(hidden).isFile()) throw new Error(`server parent root lacks ${hidden}`);
}
}
const resolverEnvironment = { ...core.environment };
resolverEnvironment.THT_WS_TASK13_SMOKE_DWH_PASSWORD_FILE = runtimePasswordMounts[0].source;
const bindings = resolveRuntimeBindings(workspace, resolverEnvironment, [dirname(runtimePasswordMounts[0].source)]);
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",
}));
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 !== runtimePasswordMounts[0].source) {
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(runtimePasswordMounts[0].source, "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");