/** * ECS's verdict on the service deployment a lane's own `UpdateService` * started (FJL-997). The rollout poll judges the PRIMARY deployment, and * ECS's rollback replaces it: a deployment whose migrate hook failed starts no * task and leaves only its rollback, which completes, so the poll reads * success. A lane that rolls ECS directly judges the deployment it started * instead, read through the service-deployment API. When that read is denied * or fails, it still refuses success while PRIMARY runs another revision. * Messages carry ECS's text unmasked; the caller masks them at its sinks. */ import { type Result } from "@fjall/generator"; import type { DeployServices } from "../serviceFactory.js"; /** Clock tolerance between this process and ECS's `createdAt`. */ export declare const ROLLOUT_VERDICT_SKEW_MS = 30000; /** * How long a deployment may stay in flight after the poll saw the service * settle, and the least a verdict read after a failed poll waits. */ export declare const ROLLOUT_VERDICT_SETTLE_MS = 120000; export type RolloutVerdict = { readonly kind: "succeeded"; } | { readonly kind: "failed"; readonly reason: string; readonly serviceDeployment: RolloutServiceDeployment; } | { readonly kind: "unread"; readonly why: string; }; /** ECS's own record of the deployment it ended: what the failure classifier reads. */ export interface RolloutServiceDeployment { readonly arn: string; readonly status?: string; } /** Why a rollout failed, and ECS's record of the deployment when ECS judged it. */ export interface RolloutFailure { readonly reason: string; readonly serviceDeployment?: RolloutServiceDeployment; } export interface RolloutTarget { readonly clusterArn: string; readonly serviceArn: string; /** The revision the lane registered and handed `UpdateService`. */ readonly taskDefinitionArn: string; /** Taken just before the lane's `UpdateService`. */ readonly updateStartedAt: Date; } export interface RolloutVerdictSeams { /** * The lane's cancel. It ends only the wait on a deployment still in * flight; the reads never take it, so none is cut short into a failure. */ abortSignal?: AbortSignal; settleMs?: number; pollMs?: number; now?: () => number; sleep?: (ms: number, signal?: AbortSignal) => Promise; } type EcsReads = Pick; /** * How ECS ended the deployment the lane's update started: succeeded, failed * (rolled back or stopped, with ECS's reason and record), or unread with * why. A deployment still in flight is re-read until it ends or `settleMs` * passes, or the lane is cancelled. A deployment ECS stopped because * another started hands over to the earliest later deployment of the same * task definition, as a retried UpdateService or an operator's forced * redeploy makes one. */ export declare function readRolloutVerdict(ecs: EcsReads, target: RolloutTarget, seams?: RolloutVerdictSeams): Promise; /** * A rollout judged successful: `ended` when ECS's own verdict read the * deployment as ended, `unended` when the service's PRIMARY deployment * decided in its place, so ECS may still be rolling the deployment out. */ export interface RolloutJudged { readonly deployment: "ended" | "unended"; } /** * Whether the rollout the lane started succeeded, as ECS judges it. An unread * verdict falls back to the service's PRIMARY deployment: success only while * it runs the revision the lane registered, with a warning that ECS's own * verdict could not be read. Neither readable is a failure, since the poll * alone cannot tell a completed rollout from a completed rollback. A failure * ECS judged carries ECS's record of the deployment, for the classifier. */ export declare function judgeRollout(ecs: EcsReads, target: RolloutTarget, onWarning: (message: string) => void, seams?: RolloutVerdictSeams): Promise>; export {};