fix: resolve operator snapshot paths beneath the configured registry root

This commit is contained in:
2026-08-11 19:14:24 +02:00
parent e34b756052
commit 436d8d2720
@@ -16,6 +16,7 @@ import {
writeFileSync, writeFileSync,
} from "node:fs"; } from "node:fs";
import { dirname, isAbsolute, join, relative, resolve } from "node:path"; import { dirname, isAbsolute, join, relative, resolve } from "node:path";
import { readFile as readFileAsync } from "node:fs/promises";
import { parse, parseAllDocuments, stringify } from "yaml"; import { parse, parseAllDocuments, stringify } from "yaml";
import { resolveRuntimeBindings, type RuntimeBindings } from "./bindings.js"; import { resolveRuntimeBindings, type RuntimeBindings } from "./bindings.js";
import { GitWorkspaceRepository } from "./git-repository.js"; import { GitWorkspaceRepository } from "./git-repository.js";
@@ -336,14 +337,19 @@ export async function renderActiveWorkspaceRuntime(options: {
secretRoots: readonly string[]; secretRoots: readonly string[];
semanticRuntime: SemanticRuntimeConfig; semanticRuntime: SemanticRuntimeConfig;
}): Promise<ActiveRenderedWorkspaceRuntime> { }): Promise<ActiveRenderedWorkspaceRuntime> {
const { workspace, revision } = await options.registry.read(options.workspaceId); const { revision } = await options.registry.read(options.workspaceId);
const repository = new GitWorkspaceRepository(options.registryConfig); const repository = new GitWorkspaceRepository(options.registryConfig);
await repository.ensureLayout(); await repository.ensureLayout();
// The persisted active state may reference host-side snapshot paths (written by another
// process or installation). The operator always resolves the immutable snapshot beneath its
// own configured registry root so the path is correct inside the container and on the host.
const snapshotPath = options.registry.snapshotPath(revision.commit, revision.id);
const workspace = parseWorkspaceYaml(await readFileAsync(snapshotPath, "utf8"));
const rendered = renderWorkspaceRuntimeFromWorkspace({ const rendered = renderWorkspaceRuntimeFromWorkspace({
workspace, workspace,
workspaceId: revision.id, workspaceId: revision.id,
workspaceRevision: revision.commit, workspaceRevision: revision.commit,
revisionContentRoot: dirname(revision.snapshotPath), revisionContentRoot: dirname(snapshotPath),
harnessDir: options.harnessDir, harnessDir: options.harnessDir,
configPath: options.configPath, configPath: options.configPath,
dataRoot: options.dataRoot, dataRoot: options.dataRoot,
@@ -352,7 +358,7 @@ export async function renderActiveWorkspaceRuntime(options: {
}); });
return { return {
...rendered, ...rendered,
snapshotPath: revision.snapshotPath, snapshotPath,
descriptorBlob: revision.blob, descriptorBlob: revision.blob,
catalogBlob: (await repository.catalogBlob(revision.commit)).trim(), catalogBlob: (await repository.catalogBlob(revision.commit)).trim(),
}; };