import { isVersionCompatible } from "../../src/application/policies/compatibility.ts"; import { verifyContractSet } from "../../src/contracts/contract-set.ts"; import type { InstalledContractPackageIdentity } from "../../src/contracts/external-contract-runtime.ts"; import type { ReleaseArtifact } from "../../src/contracts/release-artifacts.ts"; import { compareReleaseToRuntime } from "../../src/contracts/release-tokens.ts"; export type ReleaseRuntimeCoherenceInput = Readonly<{ release: ReleaseArtifact; runtime: Readonly<{ BUILD_ID: string; CONFIG_SCHEMA_VERSION: string; API_CONTRACT_VERSION?: string; RELEASE_ID: string; }>; contractPackages: readonly InstalledContractPackageIdentity[]; }>; export type ReleaseRuntimeCoherence = Readonly<{ compatible: boolean; mismatches: readonly string[]; warnings: readonly string[]; }>; /** * Verifies the runtime identity using the release schema's own contract model. * V1 retains the scalar compatibility policy. V2 has no scalar projection: its * identity is the exact compiled package tuple set and canonical set digest. */ export async function verifyReleaseRuntimeCoherence( input: ReleaseRuntimeCoherenceInput, ): Promise { if (input.release.schemaVersion === 1) { if (input.runtime.API_CONTRACT_VERSION === undefined) { return compareWithoutContractScalar(input, ["apiContractVersion"]); } return compareReleaseToRuntime(input.release, { ...input.runtime, API_CONTRACT_VERSION: input.runtime.API_CONTRACT_VERSION, }); } const comparison = compareWithoutContractScalar(input); const contractSet = await verifyContractSet({ expected: input.contractPackages, manifest: input.release.contractSet, }); if (contractSet.ok) return comparison; const mismatches = Object.freeze([ ...comparison.mismatches, contractSet.code, ]); return Object.freeze({ compatible: false, mismatches, warnings: comparison.warnings, }); } function compareWithoutContractScalar( input: Pick, initialMismatches: readonly string[] = [], ): ReleaseRuntimeCoherence { const mismatches = [...initialMismatches]; if (input.release.buildId !== input.runtime.BUILD_ID) { mismatches.push("buildId"); } if ( !isVersionCompatible( input.release.configSchemaVersion, input.runtime.CONFIG_SCHEMA_VERSION, ) ) { mismatches.push("configSchemaVersion"); } const warnings = input.release.releaseId === input.runtime.RELEASE_ID ? [] : ["releaseId"]; return Object.freeze({ compatible: mismatches.length === 0, mismatches: Object.freeze(mismatches), warnings: Object.freeze(warnings), }); }