import type { IDeploymentPreflightRuntimeTask, IOciPlatformDescriptorSummary, } from './deploymentpreflight.js'; import type { IDeployment } from './deployment.js'; import type { IImageRolloutStatus, IImmutableImageDeploymentPlan, IImmutableRolloutReportEnvelope, IImmutableImageTargetScope, TOciManifestMediaType, TSha256Digest, } from './immutableimage.js'; import { normalizeImmutableReleaseTag, normalizeSha256Digest, validateImageRolloutStatus, validateImmutableImageDeploymentPlan, } from './immutableimage.js'; import type { IRegistryTarget } from './registry.js'; export type TServiceDeploymentAdoptionDecision = 'GO' | 'NO-GO'; /** * Canonical sha256 hash of the complete adoption preflight snapshot. It is a * state/TOCTOU fence and must never be substituted with the OCI image digest. */ export type TServiceDeploymentAdoptionDigest = TSha256Digest & { readonly __serviceDeploymentAdoptionDigest: unique symbol; }; export type TServiceDeploymentAdoptionBlockerCode = | 'INVALID_REQUEST' | 'AUTHORIZATION_MISSING' | 'SERVICE_NOT_FOUND' | 'SERVICE_OWNERSHIP_MISMATCH' | 'SERVICE_ALREADY_IMMUTABLE' | 'SERVICE_STATE_CONFLICT' | 'REGISTRY_TARGET_MISSING' | 'REGISTRY_REFERENCE_INVALID' | 'REGISTRY_DIGEST_MISSING' | 'OCI_INDEX_REQUIRED' | 'OCI_PLATFORM_MISSING' | 'RELEASE_NOT_FOUND' | 'RELEASE_TAG_AMBIGUOUS' | 'TARGET_SCOPE_UNAVAILABLE' | 'RUNTIME_ATTESTATION_INCOMPLETE' | 'RUNTIME_DIGEST_MISMATCH'; export interface IServiceDeploymentAdoptionBlocker { code: TServiceDeploymentAdoptionBlockerCode; message: string; } export interface IServiceDeploymentAdoptionPreflightInput { requestId: string; organizationId: string; serviceId: string; } export interface IServiceDeploymentAdoptionInput extends IServiceDeploymentAdoptionPreflightInput { idempotencyKey: string; expectedAdoptionDigest: TServiceDeploymentAdoptionDigest; } export interface IServiceDeploymentAdoptionImagePromotionInput extends IServiceDeploymentAdoptionPreflightInput { targetReleaseTag: string; expectedSourceImageDigest?: TSha256Digest; idempotencyKey: string; } export interface IServiceDeploymentAdoptionImagePromotionResult { status: 'promoted' | 'already-promoted'; organizationId: string; serviceId: string; sourceTag: string; releaseTag: string; registryHost: string; repository: string; digest: TSha256Digest; mediaType: | 'application/vnd.oci.image.index.v1+json' | 'application/vnd.docker.distribution.manifest.list.v2+json'; platforms: IOciPlatformDescriptorSummary[]; releaseId: string; digestPinnedImageReference: string; } export interface IServiceDeploymentAdoptionRolloutInput extends IServiceDeploymentAdoptionPreflightInput { releaseTag: string; expectedTargetImageDigest: TSha256Digest; idempotencyKey: string; } export interface IServiceDeploymentAdoptionRolloutResult { status: | 'rollout-started' | 'rollout-in-progress' | 'rollout-succeeded' | 'rollout-failed'; idempotentReplay: boolean; operationId: string; organizationId: string; serviceId: string; registryHost: string; repository: string; releaseTag: string; digest: TSha256Digest; releaseId: string; plan: IImmutableImageDeploymentPlan; rolloutStatus: IImageRolloutStatus; } interface IServiceDeploymentAdoptionReportBase { schemaVersion: 1; mutationPerformed: false; requestId: string; generatedAt: number; runtimeAttestation: { requiredReplicaCount: number; observedReplicaCount: number; healthyReplicaCount: number; observedDigestReplicaCount: number; observedDigestConsistent: boolean; }; } interface IServiceDeploymentAdoptionServiceSnapshot { organizationId: string; serviceId: string; serviceName: string; imageId: string; deployOnPush: boolean; immutableImageRequired: boolean; configuredReference: string; /** Hash of the complete persisted pre-adoption service configuration. */ configurationDigest: TSha256Digest; registryTarget: IRegistryTarget; } interface IServiceDeploymentAdoptionRegistrySnapshot { tag?: string; digest?: TSha256Digest; mediaType?: TOciManifestMediaType; platforms: IOciPlatformDescriptorSummary[]; releaseId?: string; releaseTag?: string; } export interface IServiceDeploymentAdoptionGoReport extends IServiceDeploymentAdoptionReportBase { decision: 'GO'; service: IServiceDeploymentAdoptionServiceSnapshot & { deployOnPush: true; immutableImageRequired: false; }; registry: IServiceDeploymentAdoptionRegistrySnapshot & { tag: string; digest: TSha256Digest; mediaType: | 'application/vnd.oci.image.index.v1+json' | 'application/vnd.docker.distribution.manifest.list.v2+json'; platforms: [IOciPlatformDescriptorSummary, ...IOciPlatformDescriptorSummary[]]; releaseId: string; releaseTag: string; }; runtimeTasks: [IDeploymentPreflightRuntimeTask, ...IDeploymentPreflightRuntimeTask[]]; targetScope: IImmutableImageTargetScope; adoptionDigest: TServiceDeploymentAdoptionDigest; blockers: []; } export interface IServiceDeploymentAdoptionNoGoReport extends IServiceDeploymentAdoptionReportBase { decision: 'NO-GO'; service?: IServiceDeploymentAdoptionServiceSnapshot; registry: IServiceDeploymentAdoptionRegistrySnapshot; runtimeTasks: IDeploymentPreflightRuntimeTask[]; targetScope?: IImmutableImageTargetScope; adoptionDigest?: never; blockers: [IServiceDeploymentAdoptionBlocker, ...IServiceDeploymentAdoptionBlocker[]]; } export type IServiceDeploymentAdoptionReport = | IServiceDeploymentAdoptionGoReport | IServiceDeploymentAdoptionNoGoReport; export interface IServiceDeploymentAdoptionResult { adoptionId: string; adoptionDigest: TServiceDeploymentAdoptionDigest; idempotentReplay: boolean; plan: IImmutableImageDeploymentPlan; } export type TServiceDeploymentAdoptionRetentionPhase = 'prepare' | 'commit'; /** * A session-bound Coreflow assertion that its local live runtime can be * retained for the exact adoption plan without mutating the Docker service. */ export interface IServiceDeploymentAdoptionRetentionAttestation { schemaVersion: 1; phase: TServiceDeploymentAdoptionRetentionPhase; retainedWithoutMutation: true; serviceId: string; operationId: string; adoptionConfigurationDigest: TSha256Digest; immutableReport: IImmutableRolloutReportEnvelope; deployments: IDeployment[]; attestedAt: number; } export const validateServiceDeploymentAdoptionRetentionAttestation = ( attestationArg: unknown, ): string[] => { if (!isRecord(attestationArg)) return ['retention attestation must be an object']; const errors: string[] = []; if (attestationArg.schemaVersion !== 1) errors.push('retention attestation schemaVersion must be 1'); if (attestationArg.phase !== 'prepare' && attestationArg.phase !== 'commit') { errors.push('retention attestation phase is invalid'); } if (attestationArg.retainedWithoutMutation !== true) { errors.push('retention attestation must assert mutation-free retention'); } if (!isBoundedIdentifier(attestationArg.serviceId) || !isBoundedIdentifier(attestationArg.operationId)) { errors.push('retention attestation service and operation IDs must be bounded identifiers'); } if (!isCanonicalDigest(attestationArg.adoptionConfigurationDigest)) { errors.push('retention attestation configuration digest must be canonical'); } if (!Number.isSafeInteger(attestationArg.attestedAt) || (attestationArg.attestedAt as number) < 1) { errors.push('retention attestation timestamp must be a positive integer'); } if (!isRecord(attestationArg.immutableReport)) { errors.push('retention attestation requires an immutable report envelope'); } if (!Array.isArray(attestationArg.deployments) || attestationArg.deployments.length < 1) { errors.push('retention attestation requires at least one deployment'); } else if (attestationArg.deployments.some((deploymentArg) => ( !isRecord(deploymentArg) || deploymentArg.serviceId !== attestationArg.serviceId ))) { errors.push('retention attestation deployments must belong to the exact service'); } return errors; }; const boundaryIdentifierRegex = /^[A-Za-z0-9][A-Za-z0-9:._-]{0,199}$/; const immutableSemverReleaseTagRegex = /^(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)(?:-(?:0|[1-9][0-9]*|[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9][0-9]*|[A-Za-z-][0-9A-Za-z-]*))*)?$/; const indexMediaTypes = new Set([ 'application/vnd.oci.image.index.v1+json', 'application/vnd.docker.distribution.manifest.list.v2+json', ]); const adoptionBlockerCodes = new Set([ 'INVALID_REQUEST', 'AUTHORIZATION_MISSING', 'SERVICE_NOT_FOUND', 'SERVICE_OWNERSHIP_MISMATCH', 'SERVICE_ALREADY_IMMUTABLE', 'SERVICE_STATE_CONFLICT', 'REGISTRY_TARGET_MISSING', 'REGISTRY_REFERENCE_INVALID', 'REGISTRY_DIGEST_MISSING', 'OCI_INDEX_REQUIRED', 'OCI_PLATFORM_MISSING', 'RELEASE_NOT_FOUND', 'RELEASE_TAG_AMBIGUOUS', 'TARGET_SCOPE_UNAVAILABLE', 'RUNTIME_ATTESTATION_INCOMPLETE', 'RUNTIME_DIGEST_MISMATCH', ]); const isRecord = (valueArg: unknown): valueArg is Record => Boolean(valueArg) && typeof valueArg === 'object' && !Array.isArray(valueArg); const isBoundedIdentifier = (valueArg: unknown): valueArg is string => typeof valueArg === 'string' && boundaryIdentifierRegex.test(valueArg); const isCanonicalDigest = (valueArg: unknown): valueArg is TSha256Digest => Boolean(normalizeSha256Digest(valueArg)) && normalizeSha256Digest(valueArg) === valueArg; const isNonNegativeInteger = (valueArg: unknown): valueArg is number => Number.isSafeInteger(valueArg) && (valueArg as number) >= 0; export const normalizeServiceDeploymentAdoptionReleaseTag = ( tagArg: unknown, ): string | undefined => { const normalizedTag = normalizeImmutableReleaseTag(tagArg); return normalizedTag && immutableSemverReleaseTagRegex.test(normalizedTag) ? normalizedTag : undefined; }; export const validateServiceDeploymentAdoptionPreflightInput = ( inputArg: unknown, ): string[] => { if (!isRecord(inputArg)) return ['adoption preflight input must be an object']; const errors: string[] = []; if (!isBoundedIdentifier(inputArg.requestId)) { errors.push('requestId must be a bounded canonical identifier'); } for (const key of ['organizationId', 'serviceId'] as const) { if (!isBoundedIdentifier(inputArg[key])) { errors.push(`${key} must be a bounded canonical identifier`); } } return errors; }; export const validateServiceDeploymentAdoptionInput = (inputArg: unknown): string[] => { const errors = validateServiceDeploymentAdoptionPreflightInput(inputArg); if (!isRecord(inputArg)) return errors; if (!isBoundedIdentifier(inputArg.idempotencyKey)) { errors.push('idempotencyKey must be a bounded canonical identifier'); } if (!isCanonicalDigest(inputArg.expectedAdoptionDigest)) { errors.push('expectedAdoptionDigest must be a canonical sha256 digest'); } return errors; }; export const validateServiceDeploymentAdoptionImagePromotionInput = ( inputArg: unknown, ): string[] => { const errors = validateServiceDeploymentAdoptionPreflightInput(inputArg); if (!isRecord(inputArg)) return errors; if (!normalizeServiceDeploymentAdoptionReleaseTag(inputArg.targetReleaseTag)) { errors.push('targetReleaseTag must be a canonical OCI-safe semantic version tag'); } if (!isBoundedIdentifier(inputArg.idempotencyKey)) { errors.push('idempotencyKey must be a bounded canonical identifier'); } if (inputArg.expectedSourceImageDigest !== undefined && !isCanonicalDigest(inputArg.expectedSourceImageDigest)) { errors.push('expectedSourceImageDigest must be a canonical sha256 digest when provided'); } return errors; }; export const validateServiceDeploymentAdoptionImagePromotionResult = ( resultArg: unknown, ): string[] => { if (!isRecord(resultArg)) return ['adoption image promotion result must be an object']; const errors: string[] = []; if (resultArg.status !== 'promoted' && resultArg.status !== 'already-promoted') { errors.push('status must identify a promoted or already-promoted result'); } for (const key of ['organizationId', 'serviceId', 'releaseId'] as const) { if (!isBoundedIdentifier(resultArg[key])) { errors.push(`${key} must be a bounded canonical identifier`); } } if (typeof resultArg.sourceTag !== 'string' || resultArg.sourceTag.trim() !== resultArg.sourceTag || resultArg.sourceTag.length < 1 || resultArg.sourceTag.length > 128) { errors.push('sourceTag must be a bounded canonical registry tag'); } if (!normalizeServiceDeploymentAdoptionReleaseTag(resultArg.releaseTag)) { errors.push('releaseTag must be a canonical OCI-safe semantic version tag'); } if (typeof resultArg.registryHost !== 'string' || resultArg.registryHost.trim() !== resultArg.registryHost || !resultArg.registryHost) { errors.push('registryHost must be a non-empty canonical string'); } if (typeof resultArg.repository !== 'string' || resultArg.repository.trim() !== resultArg.repository || !resultArg.repository) { errors.push('repository must be a non-empty canonical string'); } if (!isCanonicalDigest(resultArg.digest)) { errors.push('digest must be a canonical sha256 digest'); } if (!indexMediaTypes.has(resultArg.mediaType as TOciManifestMediaType)) { errors.push('mediaType must identify an OCI image index'); } if (!Array.isArray(resultArg.platforms)) { errors.push('platforms must contain OCI platform evidence'); } else { for (const architecture of ['amd64', 'arm64']) { if (!resultArg.platforms.some((platformArg) => isRecord(platformArg) && platformArg.os === 'linux' && platformArg.architecture === architecture && platformArg.runnable === true && platformArg.manifestPresent === true && isCanonicalDigest(platformArg.digest))) { errors.push(`platforms must contain runnable linux/${architecture} evidence`); } } } if (isCanonicalDigest(resultArg.digest) && typeof resultArg.registryHost === 'string' && typeof resultArg.repository === 'string' && resultArg.digestPinnedImageReference !== `${resultArg.registryHost}/${resultArg.repository}@${resultArg.digest}`) { errors.push('digestPinnedImageReference must bind the exact registry digest'); } return errors; }; export const validateServiceDeploymentAdoptionRolloutInput = ( inputArg: unknown, ): string[] => { const errors = validateServiceDeploymentAdoptionPreflightInput(inputArg); if (!isRecord(inputArg)) return errors; if (!normalizeServiceDeploymentAdoptionReleaseTag(inputArg.releaseTag)) { errors.push('releaseTag must be a canonical OCI-safe semantic version tag'); } if (!isCanonicalDigest(inputArg.expectedTargetImageDigest)) { errors.push('expectedTargetImageDigest must be a canonical sha256 digest'); } if (!isBoundedIdentifier(inputArg.idempotencyKey)) { errors.push('idempotencyKey must be a bounded canonical identifier'); } return errors; }; export const validateServiceDeploymentAdoptionRolloutResult = ( resultArg: unknown, ): string[] => { if (!isRecord(resultArg)) return ['adoption rollout result must be an object']; const errors: string[] = []; if (![ 'rollout-started', 'rollout-in-progress', 'rollout-succeeded', 'rollout-failed', ].includes(resultArg.status as string)) { errors.push('status must identify a supported adoption rollout state'); } if (typeof resultArg.idempotentReplay !== 'boolean') { errors.push('idempotentReplay must be boolean'); } for (const key of ['operationId', 'organizationId', 'serviceId', 'releaseId'] as const) { if (!isBoundedIdentifier(resultArg[key])) errors.push(`${key} must be a bounded identifier`); } if (!normalizeServiceDeploymentAdoptionReleaseTag(resultArg.releaseTag)) { errors.push('releaseTag must be a canonical OCI-safe semantic version tag'); } if (!isCanonicalDigest(resultArg.digest)) { errors.push('digest must be a canonical sha256 digest'); } if (!isRecord(resultArg.plan)) { errors.push('plan must be present'); } else { errors.push(...validateImmutableImageDeploymentPlan( resultArg.plan as unknown as IImmutableImageDeploymentPlan, ).map((errorArg) => `plan: ${errorArg}`)); if (resultArg.plan.operationId !== resultArg.operationId || resultArg.plan.releaseId !== resultArg.releaseId || resultArg.plan.releaseTag !== resultArg.releaseTag || resultArg.plan.requestedDigest !== resultArg.digest || resultArg.plan.registryHost !== resultArg.registryHost || resultArg.plan.repository !== resultArg.repository || resultArg.plan.mode !== 'promotion' || resultArg.plan.rolloutGeneration !== 1) { errors.push('plan must bind the exact generation-one adoption rollout result'); } } if (!isRecord(resultArg.rolloutStatus)) { errors.push('rolloutStatus must be present'); } else { errors.push(...validateImageRolloutStatus( resultArg.rolloutStatus as unknown as IImageRolloutStatus, ).map((errorArg) => `rolloutStatus: ${errorArg}`)); if (isRecord(resultArg.plan) && (resultArg.rolloutStatus.rolloutId !== resultArg.plan.rolloutId || resultArg.rolloutStatus.rolloutGeneration !== resultArg.plan.rolloutGeneration || resultArg.rolloutStatus.expectedDigest !== resultArg.digest)) { errors.push('rolloutStatus must bind the exact adoption rollout plan'); } } if (isRecord(resultArg.rolloutStatus)) { const rolloutStatus = resultArg.rolloutStatus.status; const successful = rolloutStatus === 'succeeded'; const failed = rolloutStatus === 'failed' || rolloutStatus === 'mismatched' || rolloutStatus === 'rolling-back' || rolloutStatus === 'rolled-back'; if ((resultArg.status === 'rollout-succeeded') !== successful) { errors.push('rollout-succeeded must exactly match a succeeded rolloutStatus'); } if ((resultArg.status === 'rollout-failed') !== failed) { errors.push('rollout-failed must exactly match a failed or mismatched rolloutStatus'); } if ((resultArg.status === 'rollout-started' || resultArg.status === 'rollout-in-progress') && (successful || failed)) { errors.push('an active rollout result must not contain a terminal rolloutStatus'); } } if (typeof resultArg.registryHost !== 'string' || !resultArg.registryHost || typeof resultArg.repository !== 'string' || !resultArg.repository) { errors.push('registryHost and repository must be non-empty strings'); } return errors; }; export const validateServiceDeploymentAdoptionReport = (reportArg: unknown): string[] => { if (!isRecord(reportArg)) return ['adoption report must be an object']; const errors: string[] = []; if (reportArg.schemaVersion !== 1) errors.push('schemaVersion must be 1'); if (reportArg.mutationPerformed !== false) { errors.push('adoption preflight must be mutation-free'); } if (!isBoundedIdentifier(reportArg.requestId)) { errors.push('requestId must be a bounded canonical identifier'); } if (!isNonNegativeInteger(reportArg.generatedAt)) { errors.push('generatedAt must be a non-negative integer'); } if (reportArg.decision !== 'GO' && reportArg.decision !== 'NO-GO') { errors.push('decision must be GO or NO-GO'); } const attestation = reportArg.runtimeAttestation; if (!isRecord(attestation)) { errors.push('runtimeAttestation must be an object'); } else { for (const key of [ 'requiredReplicaCount', 'observedReplicaCount', 'healthyReplicaCount', 'observedDigestReplicaCount', ] as const) { if (!isNonNegativeInteger(attestation[key])) { errors.push(`runtimeAttestation.${key} must be a non-negative integer`); } } if (typeof attestation.observedDigestConsistent !== 'boolean') { errors.push('runtimeAttestation.observedDigestConsistent must be boolean'); } } const blockers = reportArg.blockers; if (!Array.isArray(blockers)) { errors.push('blockers must be an array'); } else { for (const blocker of blockers) { if (!isRecord(blocker) || !adoptionBlockerCodes.has(blocker.code as TServiceDeploymentAdoptionBlockerCode) || typeof blocker.message !== 'string' || !blocker.message.trim()) { errors.push('each blocker must contain a supported code and non-empty message'); break; } } } if (reportArg.decision === 'NO-GO') { if (Array.isArray(blockers) && blockers.length === 0) { errors.push('a NO-GO report must contain at least one blocker'); } if (reportArg.adoptionDigest !== undefined) { errors.push('a NO-GO report must not contain an adoption digest'); } return errors; } if (reportArg.decision !== 'GO') return errors; if (Array.isArray(blockers) && blockers.length !== 0) { errors.push('a GO report must not contain blockers'); } if (!isCanonicalDigest(reportArg.adoptionDigest)) { errors.push('a GO report requires a canonical adoption digest'); } const service = reportArg.service; const registry = reportArg.registry; const targetScope = reportArg.targetScope; const runtimeTasks = reportArg.runtimeTasks; if (!isRecord(service)) { errors.push('a GO report requires a service snapshot'); } else { for (const key of ['organizationId', 'serviceId', 'serviceName', 'imageId'] as const) { if (!isBoundedIdentifier(service[key])) errors.push(`service.${key} is invalid`); } if (service.deployOnPush !== true || service.immutableImageRequired !== false) { errors.push('a GO report requires the legacy mutable service state'); } if (typeof service.configuredReference !== 'string' || !service.configuredReference.trim()) { errors.push('service.configuredReference must be non-empty'); } if (!isCanonicalDigest(service.configurationDigest)) { errors.push('service.configurationDigest must be a canonical sha256 digest'); } if (!isRecord(service.registryTarget)) { errors.push('service.registryTarget must be present'); } } let registryDigest: TSha256Digest | undefined; if (!isRecord(registry)) { errors.push('a GO report requires a registry snapshot'); } else { if (!normalizeImmutableReleaseTag(registry.tag) || registry.tag !== registry.releaseTag) { errors.push('registry tag and releaseTag must be the same immutable tag'); } if (!isCanonicalDigest(registry.digest)) { errors.push('registry.digest must be a canonical sha256 digest'); } else { registryDigest = registry.digest; if (reportArg.adoptionDigest === registry.digest) { errors.push('adoption digest must be a distinct full-state fence, not the image digest'); } } if (!indexMediaTypes.has(registry.mediaType as TOciManifestMediaType)) { errors.push('registry.mediaType must identify an OCI image index'); } if (!isBoundedIdentifier(registry.releaseId)) { errors.push('registry.releaseId must be a bounded canonical identifier'); } if (!Array.isArray(registry.platforms) || registry.platforms.length === 0) { errors.push('registry.platforms must contain OCI platform evidence'); } else { for (const architecture of ['amd64', 'arm64']) { if (!registry.platforms.some((platformArg) => isRecord(platformArg) && platformArg.os === 'linux' && platformArg.architecture === architecture && platformArg.runnable === true && platformArg.manifestPresent === true && isCanonicalDigest(platformArg.digest))) { errors.push(`registry.platforms must contain runnable linux/${architecture} evidence`); } } } } let requiredReplicaCount: number | undefined; let targetNodeNames: string[] = []; let replicasPerNode: number | undefined; if (!isRecord(targetScope)) { errors.push('a GO report requires an immutable target scope'); } else { const clusterIds = targetScope.targetClusterIds; const nodeNames = targetScope.targetNodeNames; replicasPerNode = targetScope.replicasPerNode as number; requiredReplicaCount = targetScope.requiredReplicaCount as number; if (!Array.isArray(clusterIds) || clusterIds.length !== 1 || clusterIds.some((valueArg) => !isBoundedIdentifier(valueArg)) || new Set(clusterIds).size !== clusterIds.length) { errors.push('targetScope.targetClusterIds must identify exactly one attested cluster'); } if (!Array.isArray(nodeNames) || nodeNames.length === 0 || nodeNames.some((valueArg) => !isBoundedIdentifier(valueArg)) || new Set(nodeNames).size !== nodeNames.length) { errors.push('targetScope.targetNodeNames must be non-empty and unique'); } else { targetNodeNames = nodeNames as string[]; } if (!Number.isSafeInteger(replicasPerNode) || replicasPerNode < 1) { errors.push('targetScope.replicasPerNode must be a positive integer'); } if (!Number.isSafeInteger(requiredReplicaCount) || requiredReplicaCount < 1 || requiredReplicaCount !== targetNodeNames.length * (replicasPerNode || 0)) { errors.push('targetScope.requiredReplicaCount must match nodes times replicas'); } } if (!Array.isArray(runtimeTasks) || runtimeTasks.length === 0) { errors.push('a GO report requires runtime task evidence'); } else { if (requiredReplicaCount !== undefined && runtimeTasks.length !== requiredReplicaCount) { errors.push('runtime task count must equal the required replica count'); } const deploymentIds = new Set(); const taskCountsByNode = new Map(); for (const task of runtimeTasks) { if (!isRecord(task) || !isBoundedIdentifier(task.deploymentId) || deploymentIds.has(task.deploymentId as string)) { errors.push('runtime task deployment IDs must be valid and unique'); continue; } deploymentIds.add(task.deploymentId as string); if (!isBoundedIdentifier(task.nodeName) || !targetNodeNames.includes(task.nodeName)) { errors.push('every runtime task must belong to the exact target node scope'); } else { taskCountsByNode.set(task.nodeName, (taskCountsByNode.get(task.nodeName) || 0) + 1); } if (task.status !== 'running' || task.healthStatus !== 'healthy') { errors.push('every runtime task must be running and healthy'); } if (!registryDigest || task.observedDigest !== registryDigest) { errors.push('every runtime task must attest the exact registry digest'); } if (typeof task.imageReference !== 'string' || !task.imageReference.trim()) { errors.push('every runtime task must identify its image reference'); } } if (replicasPerNode !== undefined && targetNodeNames.some((nodeNameArg) => taskCountsByNode.get(nodeNameArg) !== replicasPerNode)) { errors.push('runtime task evidence must cover every target node and replica'); } } if (isRecord(attestation) && requiredReplicaCount !== undefined) { if (attestation.requiredReplicaCount !== requiredReplicaCount || attestation.observedReplicaCount !== requiredReplicaCount || attestation.healthyReplicaCount !== requiredReplicaCount || attestation.observedDigestReplicaCount !== requiredReplicaCount || attestation.observedDigestConsistent !== true) { errors.push('runtime attestation must consistently cover every required replica'); } } if (isRecord(service) && isRecord(service.registryTarget) && isRecord(registry)) { const target = service.registryTarget; if (target.protocol !== 'oci' || target.tag !== registry.tag || target.serviceId !== service.serviceId || target.imageId !== service.imageId || typeof target.registryHost !== 'string' || !target.registryHost || typeof target.repository !== 'string' || !target.repository || target.imageUrl !== `${target.registryHost}/${target.repository}:${target.tag}`) { errors.push('service registry target must exactly bind the adopted service, image, and tag'); } if (registryDigest) { const digestPinnedReference = `${target.registryHost}/${target.repository}@${registryDigest}`; const tagAndDigestReference = `${target.imageUrl}@${registryDigest}`; const configuredReferences = new Set([ target.tag, target.imageUrl, digestPinnedReference, tagAndDigestReference, ]); if (!configuredReferences.has(service.configuredReference as string)) { errors.push('service configured reference must exactly bind the adopted registry target'); } const runtimeReferences = new Set([ target.imageUrl, digestPinnedReference, tagAndDigestReference, ]); if (Array.isArray(runtimeTasks) && runtimeTasks.some((taskArg) => !isRecord(taskArg) || !runtimeReferences.has(taskArg.imageReference as string))) { errors.push('every runtime task image reference must exactly bind the adopted registry target'); } } } return errors; };