feat: P3 effective configuration, memory root, and revision-scoped records

This commit is contained in:
2026-08-12 16:01:25 +02:00
parent beaba548c1
commit e23e526966
21 changed files with 1108 additions and 44 deletions
+45 -4
View File
@@ -18,6 +18,14 @@ import {
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
import { readFile as readFileAsync } from "node:fs/promises";
import { parse, parseAllDocuments, stringify } from "yaml";
import {
buildCanonicalEffectiveConfig,
canonicalEffectiveConfigJson,
configFingerprint,
effectiveConfigIdentity,
inputFingerprint,
type CanonicalEffectiveConfig,
} from "./effective-config.js";
import { resolveRuntimeBindings, type RuntimeBindings } from "./bindings.js";
import { GitWorkspaceRepository } from "./git-repository.js";
import { WorkspaceRegistry } from "./registry.js";
@@ -63,6 +71,10 @@ export interface DeterministicRuntimeConfigLease extends RuntimeConfigLease {
catalogBlob: string;
configDigest: string;
bindingDigest: string;
effectiveConfig: CanonicalEffectiveConfig;
effectiveConfigIdentity: string;
configFingerprint: string;
inputFingerprint: string;
}
export class RuntimeConfigLeaseError extends Error {
@@ -84,6 +96,9 @@ interface PublishedRuntimeConfigManifest {
catalogBlob: string;
configDigest: string;
bindingDigest: string;
effectiveConfigIdentity: string;
configFingerprint: string;
inputFingerprint: string;
path: string;
file: {
dev: number;
@@ -230,6 +245,7 @@ function runtimePaths(dataRoot: string, workspaceId: string): RuntimePaths {
sessions: join(root, "sessions"),
artifacts: join(root, "artifacts"),
indexes: join(root, "indexes"),
memory: join(root, "memory"),
};
}
@@ -388,6 +404,9 @@ function decodePublishedRuntimeConfigManifest(value: unknown): PublishedRuntimeC
|| typeof manifest.catalogBlob !== "string"
|| typeof manifest.configDigest !== "string"
|| typeof manifest.bindingDigest !== "string"
|| typeof manifest.effectiveConfigIdentity !== "string"
|| typeof manifest.configFingerprint !== "string"
|| typeof manifest.inputFingerprint !== "string"
|| typeof manifest.path !== "string"
|| !file
|| typeof file.dev !== "number"
@@ -413,6 +432,13 @@ export async function publishDeterministicRuntimeConfigLease(options: {
}): Promise<DeterministicRuntimeConfigLease> {
const rendered = await renderActiveWorkspaceRuntime(options);
const publishedConfig = applyCollectionLifecycle(rendered.renderedConfig, "require_existing");
const renderedConfigObject = parse(rendered.renderedConfig) as Record<string, unknown>;
const effectiveConfig = buildCanonicalEffectiveConfig(renderedConfigObject);
const effectiveConfigIdentityValue = effectiveConfigIdentity(rendered.workspaceId, renderedConfigObject);
const configFingerprintValue = configFingerprint(renderedConfigObject);
const inputFingerprintValue = inputFingerprint(rendered.workspaceId, renderedConfigObject);
const identitySuffix = inputFingerprintValue.slice(7, 23);
const preprocessingRoot = ensureTrustedDirectory(join(
options.dataRoot,
"sessions",
@@ -421,8 +447,8 @@ export async function publishDeterministicRuntimeConfigLease(options: {
));
const configDirectory = ensureTrustedDirectory(join(preprocessingRoot, "runtime-config"));
const manifestDirectory = ensureTrustedDirectory(join(preprocessingRoot, "runtime-config-manifests"));
const path = join(configDirectory, `${rendered.workspaceRevision}.yaml`);
const manifestPath = join(manifestDirectory, `${rendered.workspaceRevision}.json`);
const path = join(configDirectory, `${rendered.workspaceRevision}-${identitySuffix}.yaml`);
const manifestPath = join(manifestDirectory, `${rendered.workspaceRevision}-${identitySuffix}.json`);
const configDigest = sha256(publishedConfig);
const verifyPublished = (): PublishedRuntimeConfigManifest | undefined => {
@@ -456,6 +482,9 @@ export async function publishDeterministicRuntimeConfigLease(options: {
|| manifest.catalogBlob !== rendered.catalogBlob
|| manifest.configDigest !== configDigest
|| manifest.bindingDigest !== rendered.bindingDigest
|| manifest.effectiveConfigIdentity !== effectiveConfigIdentityValue
|| manifest.configFingerprint !== configFingerprintValue
|| manifest.inputFingerprint !== inputFingerprintValue
|| manifest.path !== path
|| manifest.file.dev !== configStat!.dev
|| manifest.file.ino !== configStat!.ino
@@ -479,6 +508,10 @@ export async function publishDeterministicRuntimeConfigLease(options: {
catalogBlob: rendered.catalogBlob,
configDigest,
bindingDigest: rendered.bindingDigest,
effectiveConfig,
effectiveConfigIdentity: effectiveConfigIdentityValue,
configFingerprint: configFingerprintValue,
inputFingerprint: inputFingerprintValue,
release: () => undefined,
};
}
@@ -505,6 +538,9 @@ export async function publishDeterministicRuntimeConfigLease(options: {
catalogBlob: rendered.catalogBlob,
configDigest,
bindingDigest: rendered.bindingDigest,
effectiveConfigIdentity: effectiveConfigIdentityValue,
configFingerprint: configFingerprintValue,
inputFingerprint: inputFingerprintValue,
path,
file: {
dev: Number(publishedStat.dev),
@@ -518,7 +554,8 @@ export async function publishDeterministicRuntimeConfigLease(options: {
readStrictJson(manifestPath);
} catch (error) {
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
writeAtomicFile(manifestPath, `${JSON.stringify(manifest)}\n`, 0o600);
writeAtomicFile(manifestPath, `${JSON.stringify(manifest)}
`, 0o600);
} else {
throw error;
}
@@ -533,6 +570,10 @@ export async function publishDeterministicRuntimeConfigLease(options: {
catalogBlob: rendered.catalogBlob,
configDigest,
bindingDigest: rendered.bindingDigest,
effectiveConfig,
effectiveConfigIdentity: effectiveConfigIdentityValue,
configFingerprint: configFingerprintValue,
inputFingerprint: inputFingerprintValue,
release: () => undefined,
};
}
}