fix: bind manual production graph and snapshots

This commit is contained in:
2026-08-10 00:38:46 +02:00
parent c10857405a
commit e97f335b88
4 changed files with 58 additions and 7 deletions
+22 -1
View File
@@ -1,5 +1,6 @@
#!/usr/bin/env node
import { spawnSync } from "node:child_process";
import { createHash } from "node:crypto";
import { lstatSync, realpathSync } from "node:fs";
import { lstat, mkdir, readFile, realpath } from "node:fs/promises";
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
@@ -90,6 +91,16 @@ export async function renderOwnedSnapshot({ repositoryRoot = defaultRepositoryRo
if (!match || !HEX40.test(match[1])) throw new Error("snapshot is not commit addressed");
assertNoSymlinks(root, snapshot); const snapshotEntry = await lstat(snapshot);
if (!snapshotEntry.isFile() || snapshotEntry.isSymbolicLink() || await realpath(snapshot) !== snapshot) throw new Error("snapshot is unsafe");
const snapshotBytes = await readFile(snapshot);
const snapshotDigest = createHash("sha256").update(snapshotBytes).digest("hex");
const manifestPath = join(dirname(snapshot), "snapshot.json");
assertNoSymlinks(root, manifestPath);
const manifestEntry = await lstat(manifestPath);
if (!manifestEntry.isFile() || manifestEntry.isSymbolicLink() || await realpath(manifestPath) !== manifestPath) throw new Error("snapshot manifest is unsafe");
let manifest;
try { manifest = JSON.parse(await readFile(manifestPath, "utf8")); } catch { throw new Error("snapshot manifest is malformed"); }
const yamlName = `${match[2]}.yaml`;
if (manifest?.head !== match[1] || manifest?.files?.[yamlName] !== snapshotDigest) throw new Error("snapshot content does not match its immutable manifest");
if (!below(renderedRoot, output) || dirname(output) !== renderedRoot || !output.endsWith(".yaml")) throw new Error("output is not an owned rendered path");
assertNoSymlinks(root, dirname(output));
try { if ((await lstat(output)).isSymbolicLink()) throw new Error("output is unsafe"); } catch (error) { if (error.code !== "ENOENT") throw error; }
@@ -103,7 +114,17 @@ export async function renderOwnedSnapshot({ repositoryRoot = defaultRepositoryRo
semanticRuntime: { internalQdrantUrl: "http://qdrant:6333", internalEmbeddingUrl: "http://embedding:11434", internalEmbeddingModel: "qwen3-embedding:0.6b", internalEmbeddingDimensions: 1024 },
});
let lease;
try { lease = runner.acquireWorkspaceRuntime(snapshot); if(beforePublish)await beforePublish({output,renderedRoot}); await atomicCopy(lease.path, output); }
try {
lease = runner.acquireWorkspaceRuntime(snapshot);
const verifySnapshot = async () => {
const current = await readFile(snapshot);
if (createHash("sha256").update(current).digest("hex") !== snapshotDigest) throw new Error("snapshot content changed during rendering");
};
await verifySnapshot();
if(beforePublish)await beforePublish({output,renderedRoot});
await verifySnapshot();
await atomicCopy(lease.path, output);
}
finally {
if (lease) lease.release();
for (const key of Object.keys(env)) { if (prior[key] === undefined) delete process.env[key]; else process.env[key] = prior[key]; }