import assert from "node:assert/strict"; import { execFile as callback } from "node:child_process"; import { promisify } from "node:util"; import { mkdtemp, mkdir, writeFile, readFile, rm, symlink } from "node:fs/promises"; import path from "node:path"; import os from "node:os"; import test from "node:test"; import { pathToFileURL } from "node:url"; import { materializeWorkspaceSources, workspaceSourcePin } from "../src/capability-language/source-closure.js"; import { prepareDevelopmentSources } from "../src/capability-language/development-sources.js"; import { backupWorkspaceSources, restoreWorkspaceSources } from "../src/capability-language/source-backup.js"; const exec = promisify(callback); const lock = (resources: string) => `quixos-lock version 1 { quixos source { repository "https://unavailable.test/toolchain.git"; commit "${"a".repeat(40)}"; } ${resources} }`; test("exact source closure recovers through explicitly selected bundles, preserves history and rejects edits", async (context) => { const temporary = await mkdtemp(path.join(os.tmpdir(), "qx-closure-")); context.after(() => rm(temporary, { recursive: true, force: true })); const locations: Record = {}; const repository = async (name: string, resources: string) => { const directory = path.join(temporary, name); await mkdir(directory); const git = async (...args: string[]) => (await exec("git", args, { cwd: directory })).stdout.trim(); await git("init"); await writeFile(path.join(directory, "quixos.lock"), lock("")); await git("add", "."); const commit = async () => { await git("-c", "user.name=Test", "-c", "user.email=test@example.test", "commit", "-am", "Source"); return await git("rev-parse", "HEAD"); }; const parent = await commit(); await writeFile(path.join(directory, "quixos.lock"), lock(resources)); await writeFile(path.join(directory, "marker"), name); await git("add", "."); const rev = await commit(); await git("tag", `quixos-reachability/${rev}`); const bundle = path.join(temporary, `${name}.bundle`); await git("bundle", "create", bundle, `refs/tags/quixos-reachability/${rev}`); const source = { repository: `https://unavailable.test/${name}.git`, commit: rev }; locations[source.repository] = pathToFileURL(bundle).href; return { ...source, parent }; }; const common = await repository("common", ""); const dependency = `interface Common source { repository "${common.repository}"; commit "${common.commit}"; }`; const left = await repository("left", dependency), right = await repository("right", dependency); const root = await repository( "root", ` package Left source { repository "${left.repository}"; commit "${left.commit}"; } package Right source { repository "${right.repository}"; commit "${right.commit}"; }`, ); const directory = path.join(temporary, "checkout"); const closure = await materializeWorkspaceSources({ source: root, directory, locations, concurrency: 2 }); assert.deepEqual( await materializeWorkspaceSources({ source: root, directory, repositoryPrefix: "https://unavailable.test/" }), closure, ); // Allow this root but not its dependencies: reject them before Git acquisition. const scopedRoot = { ...root, repository: "https://unavailable.test/selected/root.git" }; await assert.rejects( materializeWorkspaceSources({ source: scopedRoot, directory: path.join(temporary, "scoped"), locations: { ...locations, [scopedRoot.repository]: locations[root.repository] }, repositoryPrefix: "https://unavailable.test/selected/", }), /outside the acquisition boundary/, ); await assert.rejects( materializeWorkspaceSources({ source: root, directory, repositoryPrefix: "https://unavailable.test/root.git/" }), /outside the acquisition boundary/, ); assert.equal(closure.resources.length, 4, "diamond dependency is materialized once"); assert.deepEqual(JSON.parse(await readFile(path.join(directory, "sources.json"), "utf8")), closure); const rootEntry = closure.resources.find((entry) => entry.kind === "workspace")!; const rootDirectory = path.join(directory, rootEntry.directory); const rootLock = path.join(rootDirectory, "quixos.lock"); const rootBody = await readFile(rootLock, "utf8"); const outsideLock = path.join(temporary, "outside.lock"); await writeFile(outsideLock, rootBody); // Exercise the shared loader directly: committed root symlinks must not let // privileged source inspection read outside the acquired repository. const { loadQuixosLock } = await import("../src/resource-lock/index.js"); const linkedLock = path.join(temporary, "linked.lock"); await symlink(outsideLock, linkedLock); await assert.rejects(loadQuixosLock(linkedLock), /root locks must be ordinary/); const backup = path.join(temporary, "retained"); const manifest = await backupWorkspaceSources({ source: root, directory, output: backup }); assert.equal(manifest.repositories.length, 4); const restored = await restoreWorkspaceSources({ backup, directory: path.join(temporary, "restored") }); assert.deepEqual(restored, closure, "Source-only recovery retains canonical identity without an available forge"); await assert.rejects(backupWorkspaceSources({ source: root, directory, output: backup }), /must not exist/); const missing = { ...manifest, repositories: manifest.repositories.filter((entry) => entry.repository !== common.repository), }; await writeFile(path.join(backup, "backup.json"), JSON.stringify(missing)); await assert.rejects( restoreWorkspaceSources({ backup, directory: path.join(temporary, "incomplete") }), /omits required repository/, ); await writeFile(path.join(backup, "backup.json"), JSON.stringify(manifest)); await writeFile(path.join(backup, manifest.repositories[0].bundle), "damaged backup"); await assert.rejects( restoreWorkspaceSources({ backup, directory: path.join(temporary, "damaged") }), /integrity mismatch/, ); assert.equal((await exec("git", ["rev-parse", "HEAD^"], { cwd: rootDirectory })).stdout.trim(), root.parent); assert.equal( (await exec("git", ["remote", "get-url", "origin"], { cwd: rootDirectory })).stdout.trim(), root.repository, ); // Cached recovery does not need the primary or the backup. assert.deepEqual(await materializeWorkspaceSources({ source: root, directory }), closure); const pinFile = path.join(temporary, "source.json"); await writeFile(pinFile, JSON.stringify(root)); const cli = path.resolve(import.meta.dirname, "../src/capability-language/tool-cli.js"); const command = await exec(process.execPath, [cli, "source-checkout", pinFile, "--dir", directory]); assert.deepEqual(JSON.parse(command.stdout), closure, "Protocol CLI preserves exact cached source identity"); const scoped = await exec(process.execPath, [ cli, "source-checkout", pinFile, "--dir", directory, "--repository-prefix", "https://unavailable.test/", ]); assert.deepEqual(JSON.parse(scoped.stdout), closure); const cliBackup = path.join(temporary, "cli-backup"); const backupCommand = await exec(process.execPath, [ cli, "source-backup", pinFile, "--dir", directory, "--output", cliBackup, ]); assert.equal(JSON.parse(backupCommand.stdout).repositories.length, 4); const restoreCommand = await exec(process.execPath, [ cli, "source-restore", cliBackup, "--dir", path.join(temporary, "cli-restore"), ]); assert.deepEqual(JSON.parse(restoreCommand.stdout), closure); const developmentCommand = await exec(process.execPath, [ cli, "source-develop", pinFile, "--dir", path.join(temporary, "cli-developer"), "--cache", directory, ]); const developmentResult = JSON.parse(developmentCommand.stdout); assert.equal(developmentResult.repositories, 4); assert.deepEqual(developmentResult.source, closure.root); const a = await prepareDevelopmentSources({ source: root, cacheDirectory: directory, directory: path.join(temporary, "a"), }); const b = await prepareDevelopmentSources({ source: root, cacheDirectory: directory, directory: path.join(temporary, "b"), }); assert.notEqual(a.workspaceId, b.workspaceId); const assigned = "f8f2f8a3-328c-45a2-847a-31869ad28ce7"; const c = await prepareDevelopmentSources({ source: root, cacheDirectory: directory, directory: path.join(temporary, "assigned"), workspaceId: assigned, }); assert.equal(c.workspaceId, assigned); assert.equal( JSON.parse(await readFile(path.join(c.directory, ".quixos/resource-graph.json"), "utf8")).workspaceId, assigned, ); await assert.rejects( prepareDevelopmentSources({ source: root, cacheDirectory: directory, directory: path.join(temporary, "invalid"), workspaceId: "not-a-workspace", }), /Workspace UUID/, ); const aRoot = path.join(a.directory, "root"), bRoot = path.join(b.directory, "root"); assert.equal((await exec("git", ["remote", "get-url", "origin"], { cwd: aRoot })).stdout.trim(), root.repository); assert.equal( await readFile(path.join(aRoot, "quixos.lock"), "utf8"), await readFile(path.join(rootDirectory, "quixos.lock"), "utf8"), ); await exec("git", ["cat-file", "-e", root.parent], { cwd: aRoot }); await writeFile(path.join(aRoot, "marker"), "Independent developer change"); assert.equal(await readFile(path.join(bRoot, "marker"), "utf8"), "root"); assert.equal(await readFile(path.join(rootDirectory, "marker"), "utf8"), "root"); await assert.rejects( prepareDevelopmentSources({ source: root, cacheDirectory: directory, directory: a.directory }), /never overwritten/, ); await writeFile(path.join(rootDirectory, "marker"), "edited"); await assert.rejects(materializeWorkspaceSources({ source: root, directory, locations }), /modified/); await assert.rejects( materializeWorkspaceSources({ source: root, directory: path.join(temporary, "bounded"), locations, maxRepositories: 2, }), /repository limit/, ); await assert.rejects( materializeWorkspaceSources({ source: root, directory, locations: { [root.repository]: "https://secret:password@example.test/root.git" }, }), /transport substitution/, ); }); test("Workspace pins reject floating revisions and embedded credentials", () => { assert.throws(() => workspaceSourcePin({ repository: "https://example.test/root.git", commit: "main" })); assert.throws(() => workspaceSourcePin({ repository: "https://user:password@example.test/root.git", commit: "a".repeat(40) }), ); });