Files
ThothII/backend/test/workspace-runtime-config-lease.test.ts
T
Codex 82e2c91f42
Publish documentation / publish (push) Successful in 1m27s
feat: implement memory and evidence administration with guided repairs
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.
2026-09-10 10:31:34 +02:00

370 lines
13 KiB
TypeScript

import { execFile } from "node:child_process";
import { createHash } from "node:crypto";
import {
existsSync,
mkdtempSync,
mkdirSync,
readFileSync,
rmSync,
statSync,
symlinkSync,
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { promisify } from "node:util";
import { afterEach, expect, test, vi } from "vitest";
import { parse } from "yaml";
import { WorkspaceRegistry } from "../src/workspaces/registry.js";
import {
buildCanonicalEffectiveConfig,
canonicalEffectiveConfigJson,
effectiveConfigIdentity,
} from "../src/workspaces/effective-config.js";
import type { WorkspaceRegistryConfig } from "../src/workspaces/types.js";
import {
publishDeterministicRuntimeConfigLease,
renderActiveWorkspaceRuntime,
renderWorkspaceRuntimeFromSnapshotPath,
} from "../src/workspaces/runtime-config-lease.js";
import { WorkspaceSecretStore } from "../src/workspaces/secret-store.js";
const runFile = promisify(execFile);
const roots: string[] = [];
afterEach(() => {
vi.unstubAllEnvs();
roots.splice(0).forEach((root) => rmSync(root, { recursive: true, force: true }));
});
async function git(cwd: string, args: string[]): Promise<string> {
return (await runFile("git", args, { cwd })).stdout.trim();
}
async function fixture() {
const root = mkdtempSync(join(tmpdir(), "tht-runtime-lease-"));
roots.push(root);
const remote = join(root, "remote.git");
const source = join(root, "source");
const registryRoot = join(root, "registry");
const secretRoot = join(root, "secrets");
const dataRoot = join(root, "data");
const harnessDir = join(root, "harness");
mkdirSync(harnessDir, { recursive: true });
mkdirSync(join(harnessDir, "config"), { recursive: true });
writeFileSync(join(harnessDir, "config", "tht.yaml"), `session_storage:
mode: local
profile: server
`);
await git(root, ["init", "--bare", "--initial-branch=main", remote]);
mkdirSync(source);
await git(source, ["init", "--initial-branch=main"]);
await git(source, ["config", "user.name", "Runtime Lease Test"]);
await git(source, ["config", "user.email", "runtime-lease@example.invalid"]);
writeFileSync(join(source, "thoth-workspaces.yaml"), `schema_version: 1
workspaces: [{id: psd-clinical, name: Runtime Lease}]
`);
mkdirSync(join(source, "psd-clinical", "evidence"), { recursive: true });
writeFileSync(join(source, "psd-clinical", "workspace.yaml"), `workspace:
schema_version: 4
id: psd-clinical
name: Runtime Lease
language: en
evidence:
source:
type: filesystem
uri: psd-clinical/evidence
`);
writeFileSync(join(source, "psd-clinical", "evidence", "guide.md"), `# hello
`);
await git(source, ["add", "."]);
await git(source, ["commit", "-m", "Canonical workspace"]);
await git(source, ["remote", "add", "origin", remote]);
await git(source, ["push", "origin", "main"]);
mkdirSync(secretRoot);
mkdirSync(dataRoot);
const registryConfig: WorkspaceRegistryConfig = {
root: registryRoot,
remoteUrl: remote,
branch: "main",
gitAuthorName: "Runtime Lease Test",
gitAuthorEmail: "runtime-lease@example.invalid",
installationId: "test",
secretRoots: [secretRoot],
maxImportBytes: 1024 * 1024,
maxImportEntries: 16,
};
const registry = new WorkspaceRegistry(registryConfig);
await registry.bootstrap();
const revision = (await registry.list())[0];
const workspaceSecretStore = new WorkspaceSecretStore({
root: join(root, "vault"),
runtimeRoot: join(root, "runtime-secrets"),
installationId: "test",
});
workspaceSecretStore.putMany("psd-clinical", { "catalog.dwh.password": "secret" });
const catalogDatabase = {
id: "database-1",
workspaceId: "psd-clinical",
engine: "postgres" as const,
databaseName: "analytics",
schema: "mart",
binding: {
transport: "postgres_direct" as const,
host: "warehouse.internal",
port: 5432,
username: "reader",
},
version: 1,
createdAt: "2026-01-01T00:00:00Z",
updatedAt: "2026-01-01T00:00:00Z",
connectionStatus: "reachable" as const,
metadataContentRevision: 1,
preprocessingStatus: "failed" as const,
};
return {
dataRoot,
harnessDir,
source,
registry,
registryConfig,
revision,
workspaceSecretStore,
catalogDatabase,
};
}
const semanticRuntime = {
internalQdrantUrl: "http://qdrant:6333",
internalEmbeddingUrl: "http://embedding:11434",
internalEmbeddingModel: "qwen3-embedding:0.6b",
internalEmbeddingDimensions: 1024,
};
test("active workspace rendering is byte-identical to direct snapshot rendering", async () => {
const f = await fixture();
const direct = renderWorkspaceRuntimeFromSnapshotPath({
snapshotPath: f.revision.snapshotPath,
harnessDir: f.harnessDir,
configPath: "config/tht.yaml",
dataRoot: f.dataRoot,
secretRoots: f.registryConfig.secretRoots,
semanticRuntime,
catalogDatabase: f.catalogDatabase,
workspaceSecretStore: f.workspaceSecretStore,
});
const active = await renderActiveWorkspaceRuntime({
workspaceId: "psd-clinical",
registry: f.registry,
registryConfig: f.registryConfig,
harnessDir: f.harnessDir,
configPath: "config/tht.yaml",
dataRoot: f.dataRoot,
secretRoots: f.registryConfig.secretRoots,
semanticRuntime,
catalogDatabase: f.catalogDatabase,
workspaceSecretStore: f.workspaceSecretStore,
});
expect(active.renderedConfig).toBe(direct.renderedConfig);
expect(active.workspaceRevision).toBe(f.revision.commit);
expect(active.descriptorBlob).toMatch(/^sha256:[0-9a-f]{64}$/);
expect(active.catalogBlob).toMatch(/^sha256:[0-9a-f]{64}$/);
});
test("deterministic operator leases are keyed by logical identity and stable across calls", async () => {
const f = await fixture();
const first = await publishDeterministicRuntimeConfigLease({
workspaceId: "psd-clinical",
registry: f.registry,
registryConfig: f.registryConfig,
harnessDir: f.harnessDir,
configPath: "config/tht.yaml",
dataRoot: f.dataRoot,
secretRoots: f.registryConfig.secretRoots,
semanticRuntime,
catalogDatabase: f.catalogDatabase,
workspaceSecretStore: f.workspaceSecretStore,
});
const second = await publishDeterministicRuntimeConfigLease({
workspaceId: "psd-clinical",
registry: f.registry,
registryConfig: f.registryConfig,
harnessDir: f.harnessDir,
configPath: "config/tht.yaml",
dataRoot: f.dataRoot,
secretRoots: f.registryConfig.secretRoots,
semanticRuntime,
catalogDatabase: f.catalogDatabase,
workspaceSecretStore: f.workspaceSecretStore,
});
const suffix = createHash("sha256").update(first.inputFingerprint + "\n" + readFileSync(first.path, "utf8")).digest("hex").slice(0, 16);
expect(second.path).toBe(first.path);
expect(first.path).toBe(join(
f.dataRoot,
"sessions",
"psd-clinical",
"preprocessing",
"runtime-config",
`${f.revision.commit}-${suffix}.yaml`,
));
expect(statSync(first.path).mode & 0o777).toBe(0o400);
expect(statSync(first.manifestPath).mode & 0o777).toBe(0o600);
expect(readFileSync(first.path, "utf8")).toContain("collection_lifecycle: require_existing");
expect(readFileSync(first.path, "utf8")).toContain("memory:");
expect(existsSync(first.manifestPath)).toBe(true);
expect(first.effectiveConfigIdentity).toMatch(/^workspace:\/\/psd-clinical@v1:[0-9a-f]{64}$/);
expect(first.configFingerprint).toMatch(/^sha256:[0-9a-f]{64}$/);
expect(first.inputFingerprint).toMatch(/^sha256:[0-9a-f]{64}$/);
expect(first.inputFingerprint).not.toBe(first.configFingerprint);
const manifest = JSON.parse(readFileSync(first.manifestPath, "utf8"));
expect(manifest).toMatchObject({
schemaVersion: 1,
workspaceId: "psd-clinical",
workspaceRevision: f.revision.commit,
descriptorBlob: first.descriptorBlob,
catalogBlob: first.catalogBlob,
configDigest: first.configDigest,
bindingDigest: first.bindingDigest,
effectiveConfigIdentity: first.effectiveConfigIdentity,
configFingerprint: first.configFingerprint,
inputFingerprint: first.inputFingerprint,
path: first.path,
});
const changedDatabase = {
...f.catalogDatabase,
binding: { ...f.catalogDatabase.binding, host: "warehouse-two.internal" },
version: 2,
};
const changed = await publishDeterministicRuntimeConfigLease({
workspaceId: "psd-clinical",
registry: f.registry,
registryConfig: f.registryConfig,
harnessDir: f.harnessDir,
configPath: "config/tht.yaml",
dataRoot: f.dataRoot,
secretRoots: f.registryConfig.secretRoots,
semanticRuntime,
catalogDatabase: changedDatabase,
workspaceSecretStore: f.workspaceSecretStore,
});
expect(changed.path).not.toBe(first.path);
expect(changed.inputFingerprint).not.toBe(first.inputFingerprint);
expect(changed.configFingerprint).not.toBe(first.configFingerprint);
expect(readFileSync(changed.path, "utf8")).toContain("warehouse-two.internal");
});
test("runtime rendering rejects untrusted snapshot paths and symlinks", async () => {
const f = await fixture();
const outside = join(f.dataRoot, "outside.yaml");
writeFileSync(outside, readFileSync(f.revision.snapshotPath, "utf8"));
const symlink = join(f.dataRoot, "alias.yaml");
symlinkSync(f.revision.snapshotPath, symlink);
expect(() => renderWorkspaceRuntimeFromSnapshotPath({
snapshotPath: outside,
harnessDir: f.harnessDir,
configPath: "config/tht.yaml",
dataRoot: f.dataRoot,
secretRoots: f.registryConfig.secretRoots,
semanticRuntime,
catalogDatabase: f.catalogDatabase,
workspaceSecretStore: f.workspaceSecretStore,
})).toThrow(/trusted runtime snapshot/i);
expect(() => renderWorkspaceRuntimeFromSnapshotPath({
snapshotPath: symlink,
harnessDir: f.harnessDir,
configPath: "config/tht.yaml",
dataRoot: f.dataRoot,
secretRoots: f.registryConfig.secretRoots,
semanticRuntime,
catalogDatabase: f.catalogDatabase,
workspaceSecretStore: f.workspaceSecretStore,
})).toThrow(/trusted runtime snapshot/i);
});
test("operator lease and session snapshot produce byte-identical effective DWH bindings", async () => {
const f = await fixture();
const session = renderWorkspaceRuntimeFromSnapshotPath({
snapshotPath: f.revision.snapshotPath,
harnessDir: f.harnessDir,
configPath: "config/tht.yaml",
dataRoot: f.dataRoot,
secretRoots: f.registryConfig.secretRoots,
semanticRuntime,
catalogDatabase: f.catalogDatabase,
workspaceSecretStore: f.workspaceSecretStore,
});
const lease = await publishDeterministicRuntimeConfigLease({
workspaceId: "psd-clinical",
registry: f.registry,
registryConfig: f.registryConfig,
harnessDir: f.harnessDir,
configPath: "config/tht.yaml",
dataRoot: f.dataRoot,
secretRoots: f.registryConfig.secretRoots,
semanticRuntime,
catalogDatabase: f.catalogDatabase,
workspaceSecretStore: f.workspaceSecretStore,
});
const sessionCanonical = canonicalEffectiveConfigJson(buildCanonicalEffectiveConfig(parse(session.renderedConfig)));
const operatorCanonical = canonicalEffectiveConfigJson(lease.effectiveConfig);
expect(operatorCanonical).toBe(sessionCanonical);
expect(lease.effectiveConfigIdentity).toBe(
effectiveConfigIdentity("psd-clinical", parse(session.renderedConfig)),
);
});
test("a content-only Evidence commit keeps the same effective config identity with a new revision lease", async () => {
const f = await fixture();
const firstLease = await publishDeterministicRuntimeConfigLease({
workspaceId: "psd-clinical",
registry: f.registry,
registryConfig: f.registryConfig,
harnessDir: f.harnessDir,
configPath: "config/tht.yaml",
dataRoot: f.dataRoot,
secretRoots: f.registryConfig.secretRoots,
semanticRuntime,
catalogDatabase: f.catalogDatabase,
workspaceSecretStore: f.workspaceSecretStore,
});
const firstIdentity = firstLease.effectiveConfigIdentity;
writeFileSync(
join(f.source, "psd-clinical", "evidence", "guide.md"),
"# updated content only\n",
);
await git(f.source, ["add", "psd-clinical/evidence/guide.md"]);
await git(f.source, ["commit", "-m", "Evidence content only"]);
await git(f.source, ["push", "origin", "main"]);
await f.registry.pull();
const current = (await f.registry.list())[0];
const secondLease = await publishDeterministicRuntimeConfigLease({
workspaceId: "psd-clinical",
registry: f.registry,
registryConfig: f.registryConfig,
harnessDir: f.harnessDir,
configPath: "config/tht.yaml",
dataRoot: f.dataRoot,
secretRoots: f.registryConfig.secretRoots,
semanticRuntime,
catalogDatabase: f.catalogDatabase,
workspaceSecretStore: f.workspaceSecretStore,
});
expect(secondLease.workspaceRevision).toBe(current.commit);
expect(secondLease.workspaceRevision).not.toBe(firstLease.workspaceRevision);
expect(secondLease.effectiveConfigIdentity).toBe(firstIdentity);
expect(secondLease.path).not.toBe(firstLease.path);
});