import { execFile } from "node:child_process"; 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 { 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 = first.inputFingerprint.slice(7, 23); 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); });