import { test, expect } from "vitest"; import { chmodSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { dirname, join } from "node:path"; import { execFileSync } from "node:child_process"; import { createHash } from "node:crypto"; import { runBoundedHelper, WorkspaceRuntimeConfigLeaseFactory } from "../src/workspaces/runtime-config-lease.js"; import { parse } from "yaml"; import { parseWorkspaceYaml, serializeWorkspaceYaml } from "../src/workspaces/schema.js"; const workspace = "abc"; const descriptor = `workspace: schema_version: 3 id: ${workspace} name: Lease language: en dwh: engine: postgres database: analytics schema: mart supported_transports: [postgres_direct] semantic_index: vector_store: engine: qdrant collection: abc dimensions: 1024 distance: cosine embedding: provider: ollama_internal model: qwen3-embedding:0.6b dimensions: 1024 llm_policy: allowed: [zai/glm-5.2] `; function fixture(extraEnv: Record = {}) { const root = mkdtempSync(join(tmpdir(), "runtime-config-lease-")); const canonicalDescriptor = serializeWorkspaceYaml(parseWorkspaceYaml(descriptor)); const snapshots = join(root, "snapshots"); const repo = join(root, "repo"); mkdirSync(join(repo, "workspaces"), { recursive: true }); execFileSync("git", ["init", "--initial-branch=main"], { cwd: repo }); execFileSync("git", ["config", "user.name", "Fixture"], { cwd: repo }); execFileSync("git", ["config", "user.email", "fixture@example.invalid"], { cwd: repo }); writeFileSync(join(repo, "workspaces", `${workspace}.yaml`), canonicalDescriptor); execFileSync("git", ["add", "."], { cwd: repo }); execFileSync("git", ["commit", "-m", "fixture"], { cwd: repo }); const actualCommit = execFileSync("git", ["rev-parse", "HEAD"], { cwd: repo, encoding: "utf8" }).trim(); const blob = execFileSync("git", ["rev-parse", `HEAD:workspaces/${workspace}.yaml`], { cwd: repo, encoding: "utf8" }).trim(); const snapshotsDir = join(snapshots, actualCommit); const snapshotPath = join(snapshotsDir, `${workspace}.yaml`); const dataRoot = join(root, "data"); const harness = join(root, "harness"); mkdirSync(snapshotsDir, { recursive: true, mode: 0o700 }); chmodSync(snapshots, 0o700); const publicFiles = { [`${workspace}.yaml`]: canonicalDescriptor, [`${workspace}.env.example`]: "# fixture\n", [`${workspace}.md`]: "# Lease\n", }; for (const [name, contents] of Object.entries(publicFiles)) writeFileSync(join(snapshotsDir, name), contents, { mode: 0o400 }); writeFileSync(join(snapshotsDir, "snapshot.json"), JSON.stringify({ head: actualCommit, revisions: [{ id: workspace, commit: actualCommit, blob, snapshotPath }], files: Object.fromEntries(Object.entries(publicFiles).map(([name, contents]) => [name, createHash("sha256").update(contents).digest("hex")])), }), { mode: 0o400 }); mkdirSync(harness); const secret = join(root, "password"); writeFileSync(secret, "secret", { mode: 0o600 }); const configPath = join(harness, "config.yaml"); writeFileSync(configPath, "profile: workstation\n"); const factoryInput = { dataRoot, runtimeSnapshotRoot: snapshots, harnessDir: harness, configPath, env: { NODE_ENV: "test", THT_WS_ABC_DWH_TRANSPORT: "postgres_direct", THT_WS_ABC_DWH_HOST: "dwh", THT_WS_ABC_DWH_PORT: "5432", THT_WS_ABC_DWH_USER: "reader", THT_WS_ABC_DWH_PASSWORD_FILE: secret, ...extraEnv, }, secretRoots: [root], semanticRuntime: { internalQdrantUrl: "http://qdrant:6333", internalEmbeddingUrl: "http://embedding:11434", internalEmbeddingModel: "qwen3-embedding:0.6b", internalEmbeddingDimensions: 1024, }, }; const factory = new WorkspaceRuntimeConfigLeaseFactory(factoryInput); return { root, repo, snapshotPath, factory, factoryInput, canonicalDescriptor, snapshotManifest: join(snapshotsDir, "snapshot.json") }; } test("session and maintenance share deterministic bytes and path", async () => { const f = fixture(); try { const session = await f.factory.acquireSession(f.snapshotPath); const maintenance = await f.factory.acquireMaintenance({ snapshotPath: f.snapshotPath }); expect(session.path).toBe(maintenance.path); expect(readFileSync(session.path, "utf8")).toBe(readFileSync(maintenance.path, "utf8")); expect(lstatSync(session.path).mode & 0o777).toBe(0o400); expect(existsSync(maintenance.manifestPath)).toBe(true); const manifest = JSON.parse(readFileSync(maintenance.manifestPath, "utf8")); expect(manifest).toMatchObject({ version: 1, descriptor_dev: expect.any(String), descriptor_ino: expect.any(String) }); expect(existsSync(join(dirname(dirname(maintenance.path)), "runtime-config.lock"))).toBe(false); session.release(); maintenance.release(); expect(existsSync(session.path)).toBe(true); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("same revision changed bytes are refused", async () => { const f = fixture(); try { const first = await f.factory.acquireSession(f.snapshotPath); chmodSync(first.path, 0o600); writeFileSync(first.path, "changed", { mode: 0o600 }); chmodSync(first.path, 0o400); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/changed|mismatch|trusted/i); first.release(); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("snapshot descriptor must equal the Git canonical descriptor", async () => { const f = fixture(); try { const mutated = f.canonicalDescriptor.replace("database: analytics", "database: evil").replace("name: Lease", "name: Lease analytics"); chmodSync(f.snapshotPath, 0o600); writeFileSync(f.snapshotPath, mutated, { mode: 0o600 }); chmodSync(f.snapshotPath, 0o400); const manifestPath = join(dirname(f.snapshotPath), "snapshot.json"); const manifest = JSON.parse(readFileSync(manifestPath, "utf8")); manifest.files[`${workspace}.yaml`] = createHash("sha256").update(mutated).digest("hex"); chmodSync(manifestPath, 0o600); writeFileSync(manifestPath, JSON.stringify(manifest), { mode: 0o600 }); chmodSync(manifestPath, 0o400); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/Git descriptor|integrity|identity/i); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("same-byte replacement of the registry descriptor is refused", async () => { const f = fixture(); try { const first = await f.factory.acquireSession(f.snapshotPath); const replacement = `${f.snapshotPath}.replacement`; writeFileSync(replacement, readFileSync(f.snapshotPath), { mode: 0o400 }); chmodSync(f.snapshotPath, 0o600); rmSync(f.snapshotPath); writeFileSync(f.snapshotPath, readFileSync(replacement), { mode: 0o400 }); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/identity|changed|mismatch|trusted/i); first.release(); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("manifest binds the complete canonical destination directory chain", async () => { const f = fixture(); try { const lease = await f.factory.acquireSession(f.snapshotPath); const manifest = JSON.parse(readFileSync(lease.manifestPath, "utf8")); expect(manifest.directory_identities.length).toBeGreaterThan(5); expect(manifest.directory_identities.map((entry: { path: string }) => entry.path)).toContain( `${process.platform === "darwin" ? "/private" : ""}${join(f.root, "data", "sessions", workspace, "preprocessing")}`, ); expect(manifest.directory_identities.every((entry: Record) => ["path", "dev", "ino", "mode", "uid"].every((key) => typeof entry[key] === "string"), )).toBe(true); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("raw Git identity ignores replacement refs", async () => { const f = fixture(); try { const evil = f.canonicalDescriptor.replace("database: analytics", "database: evil"); chmodSync(join(f.repo, "workspaces", `${workspace}.yaml`), 0o600); writeFileSync(join(f.repo, "workspaces", `${workspace}.yaml`), evil); execFileSync("git", ["add", "."], { cwd: f.repo }); execFileSync("git", ["commit", "-m", "evil"], { cwd: f.repo }); const evilCommit = execFileSync("git", ["rev-parse", "HEAD"], { cwd: f.repo, encoding: "utf8" }).trim(); const oldCommit = JSON.parse(readFileSync(f.snapshotManifest, "utf8")).head; execFileSync("git", ["replace", oldCommit, evilCommit], { cwd: f.repo }); chmodSync(f.snapshotPath, 0o600); writeFileSync(f.snapshotPath, evil); chmodSync(f.snapshotPath, 0o400); const snapshot = JSON.parse(readFileSync(f.snapshotManifest, "utf8")); snapshot.files[`${workspace}.yaml`] = createHash("sha256").update(evil).digest("hex"); chmodSync(f.snapshotManifest, 0o600); writeFileSync(f.snapshotManifest, JSON.stringify(snapshot)); chmodSync(f.snapshotManifest, 0o400); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/Git descriptor|integrity|identity/i); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("replacement of canonical destination directories is refused", async () => { const f = fixture(); try { const lease = await f.factory.acquireSession(f.snapshotPath); const original = join(f.root, "data", "sessions", workspace); const moved = `${original}.moved`; renameSync(original, moved); mkdirSync(join(original, "preprocessing", "runtime-config"), { recursive: true, mode: 0o700 }); mkdirSync(join(original, "preprocessing", "runtime-config-manifests"), { recursive: true, mode: 0o700 }); renameSync(join(moved, "preprocessing", "runtime-config", `${lease.workspaceRevision}.yaml`), join(original, "preprocessing", "runtime-config", `${lease.workspaceRevision}.yaml`)); renameSync(join(moved, "preprocessing", "runtime-config-manifests", `${lease.workspaceRevision}.json`), join(original, "preprocessing", "runtime-config-manifests", `${lease.workspaceRevision}.json`)); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/changed|mismatch|same-revision|identity|trusted/i); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("rename faults fail closed and remove staging files", async () => { const f = fixture({ THT_RUNTIME_CONFIG_RENAME_FAIL: "1" }); try { await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/rename|failed/i); const runtime = join(f.root, "data", "sessions", workspace, "preprocessing"); for (const dir of ["runtime-config", "runtime-config-manifests"]) { if (existsSync(join(runtime, dir))) expect(readdirSync(join(runtime, dir)).filter((name) => name.includes("staging")).length).toBe(0); } } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("session and operator outputs retain normalized private-host policy and binding", async () => { const f = fixture({ THT_HTTP_PRIVATE_HOST_ALLOWLIST: "internal.example,warehouse.example" }); try { const session = await f.factory.acquireSession(f.snapshotPath); const maintenance = await f.factory.acquireMaintenance({ snapshotPath: f.snapshotPath }); const output = readFileSync(session.path, "utf8"); expect(output).toContain("http_private_host_allowlist"); expect(output).toContain("- internal.example"); expect(output).toContain("- warehouse.example"); expect(output).toBe(readFileSync(maintenance.path, "utf8")); const manifest = JSON.parse(readFileSync(session.manifestPath, "utf8")); expect(manifest.config_dwh_binding).toEqual({ workspace_id: expect.any(String), config_fingerprint: expect.any(String), input_fingerprint: expect.any(String), }); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("unexpected manifest fields are refused before handoff", async () => { const f = fixture(); try { const lease = await f.factory.acquireSession(f.snapshotPath); const manifest = JSON.parse(readFileSync(lease.manifestPath, "utf8")); manifest.unexpected = true; chmodSync(lease.manifestPath, 0o600); writeFileSync(lease.manifestPath, JSON.stringify(manifest)); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/manifest|invalid|changed/i); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("runtime config symlink replacement is refused", async () => { const f = fixture(); try { const lease = await f.factory.acquireSession(f.snapshotPath); const replacement = `${lease.path}.real`; writeFileSync(replacement, readFileSync(lease.path), { mode: 0o400 }); chmodSync(lease.path, 0o600); rmSync(lease.path); // A no-follow handoff must never consume this pathname. execFileSync("ln", ["-s", replacement, lease.path]); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/trusted|changed|configuration|symbolic/i); } finally { rmSync(f.root, { recursive: true, force: true }); } }); function realHarnessBinding(config: string): Record { const helper = join(process.cwd(), "..", "harness", "tht", "runtime_config_lease_io.py"); const python = join(process.cwd(), "..", "harness", ".venv", "bin", "python"); const result = JSON.parse(execFileSync(python, [helper], { cwd: join(process.cwd(), "..", "harness"), encoding: "utf8", input: JSON.stringify({ protocol_version: 1, action: "binding", config_hex: Buffer.from(config).toString("hex") }), })); const { protocol_version: _protocol, kind: _kind, ...binding } = result; return binding; } test("explicit installation overlay is canonical and has one real harness binding", async () => { const f = fixture(); const overlay = { profile: "workstation", session_storage: { type: "postgres_direct", connection: { host: "session-db", port: 5432, database: "sessions", schema: "public", user: "runtime", password: "secret", sslmode: "verify-full", } }, egress: { http_private_host_allowlist: ["zeta.example", "alpha.example", "warehouse.example"] }, }; const sessionFactory = new WorkspaceRuntimeConfigLeaseFactory({ ...f.factoryInput, installationOverlay: overlay }); const maintenanceFactory = new WorkspaceRuntimeConfigLeaseFactory({ ...f.factoryInput, installationOverlay: overlay }); try { const session = await sessionFactory.acquireSession(f.snapshotPath); const maintenance = await maintenanceFactory.acquireMaintenance({ workspaceConfigPath: f.snapshotPath }); const sessionYaml = readFileSync(session.path, "utf8"); const maintenanceYaml = readFileSync(maintenance.path, "utf8"); expect(session.path).toBe(maintenance.path); expect(sessionYaml).toBe(maintenanceYaml); expect(parse(sessionYaml)).toMatchObject({ profile: overlay.profile, session_storage: overlay.session_storage, egress: { http_private_host_allowlist: ["alpha.example", "warehouse.example", "zeta.example"] }, }); const firstBinding = realHarnessBinding(sessionYaml); const secondBinding = realHarnessBinding(maintenanceYaml); expect(firstBinding).toEqual(secondBinding); expect(JSON.parse(readFileSync(session.manifestPath, "utf8")).config_dwh_binding).toEqual(firstBinding); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test.each([ ["config-file", "config-file"], ["config-parent", "config-parent"], ["manifest-file", "manifest-file"], ["manifest-parent", "manifest-parent"], ] as const)("fsync fault at %s fails closed and retries to the same durable pair", async (_label, stage) => { const f = fixture({ THT_RUNTIME_CONFIG_FSYNC_FAIL: stage }); try { await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/fsync|failed/i); const runtime = join(f.root, "data", "sessions", workspace, "preprocessing"); for (const dir of ["runtime-config", "runtime-config-manifests"]) { if (existsSync(join(runtime, dir))) { expect(readdirSync(join(runtime, dir)).filter((name) => name.includes("staging")).length).toBe(0); } } const recovered = new WorkspaceRuntimeConfigLeaseFactory({ ...f.factoryInput, env: { ...f.factoryInput.env, THT_RUNTIME_CONFIG_FSYNC_FAIL: undefined, } }); const lease = await recovered.acquireSession(f.snapshotPath); expect(existsSync(lease.path)).toBe(true); expect(existsSync(lease.manifestPath)).toBe(true); expect(JSON.parse(readFileSync(lease.manifestPath, "utf8")).config_sha256) .toBe(createHash("sha256").update(readFileSync(lease.path)).digest("hex")); } finally { rmSync(f.root, { recursive: true, force: true }); } }); for (const [label, mutate] of [ ["wrong commit", (f: ReturnType) => f.snapshotPath.replace(/\/[0-9a-f]{40}\//, "/" + "0".repeat(40) + "/")], ["outside path", (f: ReturnType) => join(f.root, "outside.yaml")], ["wrong workspace id", (f: ReturnType) => f.snapshotPath.replace("abc.yaml", "abd.yaml")], ] as const) { test(`rejects ${label} before publication`, async () => { const f = fixture(); try { await expect(f.factory.acquireSession(mutate(f))).rejects.toThrow(/trusted|snapshot|identity|path|Git|unavailable|ENOENT|No such/i); } finally { rmSync(f.root, { recursive: true, force: true }); } }); } for (const [label, replace] of [ ["descriptor symlink", (path: string, root: string) => { const target = `${path}.target`; writeFileSync(target, readFileSync(path), { mode: 0o400 }); rmSync(path); execFileSync("ln", ["-s", target, path]); }], ["descriptor hardlink", (path: string, root: string) => { const target = `${path}.target`; execFileSync("ln", [path, target]); rmSync(path); execFileSync("ln", [target, path]); }], ] as const) { test(`rejects ${label}`, async () => { const f = fixture(); try { replace(f.snapshotPath, f.root); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/trusted|integrity|identity|link/i); } finally { rmSync(f.root, { recursive: true, force: true }); } }); } for (const [label, target] of [ ["config symlink", "config"], ["config hardlink", "config"], ["manifest symlink", "manifest"], ["manifest hardlink", "manifest"], ] as const) { test(`rejects destination ${label} and recovers safely`, async () => { const f = fixture(); try { const first = await f.factory.acquireSession(f.snapshotPath); const path = target === "config" ? first.path : first.manifestPath; const backup = `${path}.target`; writeFileSync(backup, readFileSync(path), { mode: target === "config" ? 0o400 : 0o600 }); rmSync(path); if (label.includes("symlink")) execFileSync("ln", ["-s", backup, path]); else execFileSync("ln", [backup, path]); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/trusted|configuration|manifest|link|changed/i); rmSync(path); // A replaced inode can never be trusted again. Remove the paired durable // publication and let a fresh no-replace publication recover the layout. rmSync(first.path, { force: true }); rmSync(first.manifestPath, { force: true }); const recovered = await f.factory.acquireSession(f.snapshotPath); expect(recovered.path).toBe(first.path); } finally { rmSync(f.root, { recursive: true, force: true }); } }); } for (const [label, target, mode] of [ ["config", "config", 0o600], ["manifest", "manifest", 0o400], ] as const) { test(`refuses wrong ${label} mode then recovers after restoring mode`, async () => { const f = fixture(); try { const first = await f.factory.acquireSession(f.snapshotPath); const path = target === "config" ? first.path : first.manifestPath; chmodSync(path, mode); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/trusted|mode|configuration|manifest/i); chmodSync(path, target === "config" ? 0o400 : 0o600); await expect(f.factory.acquireSession(f.snapshotPath)).resolves.toBeDefined(); } finally { rmSync(f.root, { recursive: true, force: true }); } }); } test("release retains durable state while changed binding is refused by a new factory", async () => { const f = fixture(); try { const first = await f.factory.acquireSession(f.snapshotPath); first.release(); const changed = new WorkspaceRuntimeConfigLeaseFactory({ ...f.factoryInput, env: { ...f.factoryInput.env, THT_WS_ABC_DWH_HOST: "other-dwh", } }); await expect(changed.acquireSession(f.snapshotPath)).rejects.toThrow(/changed|mismatch|configuration/i); expect(existsSync(first.path)).toBe(true); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("strict manifest rejects an extra field and recovery preserves exact bytes", async () => { const f = fixture(); try { const first = await f.factory.acquireSession(f.snapshotPath); const original = readFileSync(first.manifestPath, "utf8"); const manifest = JSON.parse(original); manifest.extra = "reject"; chmodSync(first.manifestPath, 0o600); writeFileSync(first.manifestPath, JSON.stringify(manifest), { mode: 0o600 }); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/manifest|invalid|changed/i); writeFileSync(first.manifestPath, original, { mode: 0o600 }); await expect(f.factory.acquireSession(f.snapshotPath)).resolves.toBeDefined(); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test.each([ ["duplicate", "alpha.example,alpha.example"], ["uppercase", "Alpha.example"], ["ip address", "127.0.0.1"], ] as const)("rejects %s private-host policy", async (_label, allowlist) => { expect(() => fixture({ THT_HTTP_PRIVATE_HOST_ALLOWLIST: allowlist })) .toThrow(/allowlist|hostname|duplicate|invalid/i); }); test.each([ ["runtime-config", "config"], ["runtime-config-manifests", "manifest"], ] as const)("rejects a replaced %s destination ancestor", async (directory, _kind) => { const f = fixture(); try { const lease = await f.factory.acquireSession(f.snapshotPath); const parent = join(f.root, "data", "sessions", workspace, "preprocessing", directory); const moved = `${parent}.moved`; renameSync(parent, moved); execFileSync("ln", ["-s", moved, parent]); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/trusted|symbolic|changed|directory/i); rmSync(parent); renameSync(moved, parent); await expect(f.factory.acquireSession(f.snapshotPath)).resolves.toBeDefined(); lease.release(); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("release is idempotent and does not remove either durable publication", async () => { const f = fixture(); try { const lease = await f.factory.acquireSession(f.snapshotPath); lease.release(); lease.release(); expect(existsSync(lease.path)).toBe(true); expect(existsSync(lease.manifestPath)).toBe(true); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("partial os.write calls are completed by the real Python publication helper", async () => { const python = join(process.cwd(), "..", "harness", ".venv", "bin", "python"); const helper = join(process.cwd(), "..", "harness", "tht", "runtime_config_lease_io.py"); const code = `import os, sys; sys.path.insert(0, ${JSON.stringify(dirname(helper))}); import runtime_config_lease_io as m; real=os.write; os.write=lambda fd,b: real(fd,b[:3]); m.write_all(1, b'partial-write-ok\\n')`; const output = execFileSync(python, ["-c", code], { encoding: "utf8" }); expect(output).toBe("partial-write-ok\n"); }); test("a clean existing equal publication is reconciled by a new factory", async () => { const f = fixture(); try { const first = await f.factory.acquireSession(f.snapshotPath); const second = await new WorkspaceRuntimeConfigLeaseFactory(f.factoryInput).acquireMaintenance({ snapshotPath: f.snapshotPath }); expect(readFileSync(second.path)).toEqual(readFileSync(first.path)); expect(readFileSync(second.manifestPath)).toEqual(readFileSync(first.manifestPath)); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test.each([["config"], ["manifest"]] as const)("rename failure is scoped to the %s branch and leaves no staging", async (kind) => { const f = fixture({ THT_RUNTIME_CONFIG_RENAME_FAIL: kind }); try { await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/rename|failed/i); const runtime = join(f.root, "data", "sessions", workspace, "preprocessing"); for (const dir of ["runtime-config", "runtime-config-manifests"]) { if (existsSync(join(runtime, dir))) expect(readdirSync(join(runtime, dir)).some((name) => name.includes("staging"))).toBe(false); } } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("snapshot manifest rejects an undeclared extra immutable file", async () => { const f = fixture(); try { const snapshot = JSON.parse(readFileSync(f.snapshotManifest, "utf8")); writeFileSync(join(dirname(f.snapshotPath), "smuggled.txt"), "smuggled", { mode: 0o400 }); snapshot.files["smuggled.txt"] = createHash("sha256").update("smuggled").digest("hex"); chmodSync(f.snapshotManifest, 0o600); writeFileSync(f.snapshotManifest, JSON.stringify(snapshot), { mode: 0o400 }); await expect(f.factory.acquireSession(f.snapshotPath)).rejects.toThrow(/integrity|snapshot|trusted/i); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("independent OS publishers converge when equal and elect one winner when unequal", async () => { const f = fixture(); try { const seed = await f.factory.acquireSession(f.snapshotPath); const full = JSON.parse(readFileSync(seed.manifestPath, "utf8")); const base = Object.fromEntries(["workspace_id", "workspace_revision", "descriptor_git_blob", "descriptor_sha256", "descriptor_dev", "descriptor_ino", "config_dwh_binding"] .map((key) => [key, full[key]])); const python = join(process.cwd(), "..", "harness", ".venv", "bin", "python"); const helper = join(process.cwd(), "..", "harness", "tht", "runtime_config_lease_io.py"); const configBytes = readFileSync(seed.path); // Leave the workspace-owned destination directories in place, but remove // both durable leaves: the following OS processes race on a clean layout. rmSync(seed.path); rmSync(seed.manifestPath); const payload = JSON.stringify({ protocol_version: 1, action: "publish", data_root: f.factoryInput.dataRoot, workspace_id: workspace, workspace_revision: full.workspace_revision, config_hex: Buffer.from(configBytes).toString("hex"), manifest_base: base }); const code = `import json,multiprocessing,sys multiprocessing.set_start_method("fork") sys.path.insert(0, ${JSON.stringify(dirname(helper))}) import runtime_config_lease_io as m import contextlib,os def run(x): try: with open(os.devnull,"w") as error, contextlib.redirect_stderr(error): m.publish(x) except Exception: raise SystemExit(1) x=json.loads(sys.argv[1]); y=json.loads(sys.argv[1]) if len(sys.argv)>2: y["config_hex"]="646966666572656e742d72756e74696d652d636f6e666967" p=[multiprocessing.Process(target=run,args=(x,)),multiprocessing.Process(target=run,args=(y,))] [q.start() for q in p]; [q.join() for q in p] print(json.dumps([q.exitcode for q in p]))` const equal = JSON.parse(execFileSync(python, ["-c", code, payload], { encoding: "utf8" }).trim()); expect(equal.sort()).toEqual([0, 0]); rmSync(join(f.factoryInput.dataRoot, "sessions", workspace, "preprocessing", "runtime-config", `${full.workspace_revision}.yaml`)); rmSync(join(f.factoryInput.dataRoot, "sessions", workspace, "preprocessing", "runtime-config-manifests", `${full.workspace_revision}.json`)); const unequalPayload = JSON.stringify({ ...JSON.parse(payload), config_hex: Buffer.from("different-runtime-config").toString("hex") }); const unequal = JSON.parse(execFileSync(python, ["-c", code, payload, "unequal"], { encoding: "utf8" }).trim()); expect(unequal.filter((exit: number) => exit === 0)).toHaveLength(1); expect(unequal.filter((exit: number) => exit !== 0)).toHaveLength(1); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test.each(["leaf", "ancestor"] as const)("actual harness rejects canonical %s swap", async (kind) => { const f = fixture(); try { const lease = await f.factory.acquireSession(f.snapshotPath); const harnessBin = join(process.cwd(), "..", "harness", ".venv", "bin", "tht"); const harnessCwd = join(process.cwd(), "..", "harness"); const env = { ...process.env, THT_RUNTIME_CONFIG_MANIFEST_SHA256: lease.manifestSha256 }; if (kind === "leaf") { const moved = `${lease.path}.moved`; renameSync(lease.path, moved); execFileSync("ln", ["-s", moved, lease.path]); } else { const parent = dirname(lease.path); const moved = `${parent}.moved`; renameSync(parent, moved); execFileSync("ln", ["-s", moved, parent]); } expect(() => execFileSync(harnessBin, ["config", "check", "-c", lease.path], { cwd: harnessCwd, env, stdio: "pipe", })).toThrow(); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("actual harness rejects a workspace chain swap between config and manifest traversal", async () => { const f = fixture(); try { const lease = await f.factory.acquireSession(f.snapshotPath); const python = join(process.cwd(), "..", "harness", ".venv", "bin", "python"); const helper = join(process.cwd(), "..", "harness", "tht"); const workspaceRoot = join(f.factoryInput.dataRoot, "sessions", workspace); const code = `import os,sys from pathlib import Path sys.path.insert(0, sys.argv[3]) from tht.config import ConfigError, _read_runtime_config_source config_path = Path(sys.argv[1]) workspace = Path(sys.argv[2]) revision = config_path.stem def swap_workspace_chain(): moved = Path(str(workspace) + ".moved") os.rename(workspace, moved) (workspace / "preprocessing").mkdir(parents=True, mode=0o700) for name, leaf in (("runtime-config", revision + ".yaml"), ("runtime-config-manifests", revision + ".json")): source = moved / "preprocessing" / name destination = workspace / "preprocessing" / name original_inode = os.stat(source).st_ino original_leaf_inode = os.stat(source / leaf).st_ino os.rename(source, destination) assert os.stat(destination).st_ino == original_inode assert os.stat(destination / leaf).st_ino == original_leaf_inode try: _read_runtime_config_source( config_path, between_config_and_manifest_traversal=swap_workspace_chain, ) except ConfigError: print("rejected") else: raise SystemExit("secure reader accepted a replaced workspace chain") `; const output = execFileSync(python, ["-c", code, lease.path, workspaceRoot, helper], { cwd: join(process.cwd(), "..", "harness"), env: { ...process.env, THT_RUNTIME_CONFIG_MANIFEST_SHA256: lease.manifestSha256 }, encoding: "utf8", }); expect(output.trim()).toBe("rejected"); } finally { rmSync(f.root, { recursive: true, force: true }); } }); test("bounded helper settles early stdin close and a never-reading child without crashing", async () => { const options = (action: string, payload: string, timeoutMs = 200) => ({ cwd: tmpdir(), env: process.env, action, payload, timeoutMs, }); await expect(runBoundedHelper(process.execPath, ["-e", "process.stdin.destroy(); setTimeout(() => {}, 1000)"], options("early-close", "x".repeat(16 * 1024 * 1024)))).rejects.toThrow(); const started = Date.now(); const timer = new Promise((resolve) => setTimeout(resolve, 20)); await expect(runBoundedHelper(process.execPath, ["-e", "setTimeout(() => {}, 10000)"], options("never-read", "x".repeat(16 * 1024 * 1024), 80))).rejects.toThrow(/timed out|pipe|closed/i); await timer; expect(Date.now() - started).toBeLessThan(2_000); });