feat: bounded Evidence materializer with manifest and atomic publication (P6)
This commit is contained in:
@@ -332,6 +332,32 @@ export class GitWorkspaceRepository {
|
||||
return this.gitBlobBytes(objectId, maxBytes, "Evidence");
|
||||
}
|
||||
|
||||
/** Return the 40-hex tree id of a canonical Evidence root at an exact commit. */
|
||||
async evidenceTreeId(revision: string, id: string): Promise<string> {
|
||||
if (!/^[0-9a-f]{40}$/.test(revision) || !/^[a-z][a-z0-9-]{2,62}$/.test(id)) {
|
||||
throw new WorkspaceRegistryError("workspace_invalid", "Workspace Evidence revision is invalid");
|
||||
}
|
||||
const objectId = (await this.git(["rev-parse", `${revision}:${id}/evidence`])).trim();
|
||||
const type = (await this.git(["cat-file", "-t", objectId])).trim();
|
||||
if (!/^[0-9a-f]{40}$/.test(objectId) || type !== "tree") {
|
||||
throw new WorkspaceRegistryError("workspace_invalid", "Workspace Evidence root is invalid");
|
||||
}
|
||||
return objectId;
|
||||
}
|
||||
|
||||
/** Return the byte size of one Git object without reading its contents. */
|
||||
async gitObjectSize(objectId: string): Promise<number> {
|
||||
if (!/^[0-9a-f]{40}$/.test(objectId)) {
|
||||
throw new WorkspaceRegistryError("workspace_invalid", "Workspace Evidence object is invalid");
|
||||
}
|
||||
const raw = (await this.git(["cat-file", "-s", objectId])).trim();
|
||||
const size = Number(raw);
|
||||
if (!Number.isSafeInteger(size) || size < 0) {
|
||||
throw new WorkspaceRegistryError("workspace_invalid", "Workspace Evidence object size is invalid");
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
private async gitBlobBytes(objectId: string, maxBytes: number, label: string): Promise<Buffer> {
|
||||
if (!/^[0-9a-f]{40}$/.test(objectId)) {
|
||||
throw new WorkspaceRegistryError("workspace_invalid", `Workspace ${label} object is invalid`);
|
||||
|
||||
Reference in New Issue
Block a user