feat: bind evidence trees to registry revisions

This commit is contained in:
2026-08-09 18:39:11 +02:00
parent 033809b1b6
commit 521288eb04
4 changed files with 320 additions and 6 deletions
+25 -1
View File
@@ -154,6 +154,22 @@ export class GitWorkspaceRepository {
return (await this.git(["rev-parse", `HEAD:${path}`])).trim();
}
/** Assert that a canonical Evidence root is a Git tree at an exact commit. */
async assertTreeAtRevision(revision: string, repoRelativePath: string): Promise<void> {
if (!/^[0-9a-f]{40}$/.test(revision)
|| !/^workspace-content\/[a-z][a-z0-9-]{2,62}\/evidence$/.test(repoRelativePath)) {
throw new WorkspaceRegistryError("workspace_invalid", "Workspace Evidence revision is invalid");
}
const type = (await this.git(
["cat-file", "-t", `${revision}:${repoRelativePath}`],
{},
"Workspace Evidence root is invalid",
)).trim();
if (type !== "tree") {
throw new WorkspaceRegistryError("workspace_invalid", "Workspace Evidence root is invalid");
}
}
/** Write only a validated registry artifact below the checked-out repository. */
async writeRegistryFile(path: string, source: string): Promise<void> {
this.assertRegistryArtifactPath(path);
@@ -249,7 +265,11 @@ export class GitWorkspaceRepository {
}
}
private async git(args: string[], env: NodeJS.ProcessEnv = {}): Promise<string> {
private async git(
args: string[],
env: NodeJS.ProcessEnv = {},
invalidObjectMessage?: string,
): Promise<string> {
try {
const { stdout } = await execFileAsync(
"git",
@@ -258,6 +278,10 @@ export class GitWorkspaceRepository {
);
return stdout;
} catch (error) {
if (invalidObjectMessage && typeof error === "object" && error !== null
&& "code" in error && typeof error.code === "number") {
throw new WorkspaceRegistryError("workspace_invalid", invalidObjectMessage);
}
throw this.sanitizeGitError(error);
}
}