Add exact recursive source checkout, independent Git/jj developer workbenches and source-only backup/recovery commands, with Workspace instance binding outside source. Qualify two empty Reader Graphs, packaged source commands, Agent VM compilation, exact Gitea read grants and reconciled Reader settings/annotation stability. Publish checked Reader Package/root revisions to canonical review branches and retention tags, retain all 57 repositories independently in private versioned storage, verify downloaded-backup recovery and advance the example pin. Add bounded Central pin acquisition and selection-specific read-only identities, qualified against all 57 canonical repositories without write authority. Replace regex fork dependency discovery with compiler-parsed lock imports and rewrite proposals; preserve source identities and unrelated files, passing instance binding through packed and ordinary host checks. Hosted run-pin versus authoring preparation and maintained duplicate removal remain pending. Live source selections, Template defaults and default source branches are unchanged.
216 lines
9.9 KiB
TypeScript
216 lines
9.9 KiB
TypeScript
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<string, string> = {};
|
|
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 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) }),
|
|
);
|
|
});
|