import type { ResourceEvent } from "@fjall/util/aws"; import type { DeployCallbacks } from "../../types/callbacks.js"; import type { EcsService } from "../../services/infrastructure/EcsService.js"; import type { EcsRollbackVerdict } from "../../types/ecsRollbackVerdict.js"; export declare const ECS_TAIL_POLL_INTERVAL_MS = 15000; /** * The unstick guidance printed when a stack reaches UPDATE_ROLLBACK_FAILED. * Deliberately generic AWS remediation — deploy-core ships to customers, so * no fjall-internal references belong here. */ export declare const UPDATE_ROLLBACK_FAILED_RUNBOOK: string; export interface EcsDeploymentTail { /** * Feed every CFN resource event here. ECS service events start * supervision, and the stack's UPDATE_ROLLBACK_IN_PROGRESS is how a * replacement is put down to CloudFormation's rollback. */ observeResourceEvent(event: ResourceEvent): void; /** * Stop polling, take a final snapshot per supervised service, and emit * `onECSComplete`. Never throws; safe to call when nothing was supervised. * Services where no fresh deployment was ever adopted (e.g. a * desiredCount-only update that creates no new deployment) emit nothing. * When the last observation is non-terminal and no final snapshot is * available, `deploySucceeded` decides the verdict — CloudFormation only * reports a successful stack once the service stabilised. */ finalise(outcome?: { deploySucceeded?: boolean; }): Promise; /** * ECS's verdicts that it rolled back the deployment CloudFormation started, * at most one per service. The engine's hung-update watch reads them. */ rollbackVerdicts(): readonly EcsRollbackVerdict[]; } /** * Which of the tails reading one deploy's stack events prints the * UPDATE_ROLLBACK_FAILED runbook: the first to read such an event. */ export interface RunbookLatch { /** True the first time it is asked, false after. */ claim(): boolean; } /** A latch for one deploy, so the runbook prints once however many tails read the event. */ export declare function runbookLatch(): RunbookLatch; export interface EcsDeploymentTailDeps { ecsService: EcsService; callbacks: DeployCallbacks; abortSignal?: AbortSignal; /** The latch the deploy's tails share; a tail on its own takes one of its own. */ runbook?: RunbookLatch; /** Test seam — production callers use the default. */ pollIntervalMs?: number; /** Test seam: the local clock a rollback verdict's observation is read from. */ now?: () => number; } /** * Observe-only ECS supervision for the full CFN deploy path (the seam the * callback vocabulary at `types/callbacks.ts` reserves as "the future * full-deploy ECS-tail step"). While CloudFormation drives a rolling update, * this tail follows the service deployment CloudFormation started and the * deployment rolling out its task definition, counts distinct stopped tasks * started by it, and narrates stopped-task forensics (`stoppedReason`, * container exit codes) and ECS's own service events (a task it could not * place, say) that are otherwise invisible until someone opens the console. * It never cancels anything itself, and CFN remains the deploy authority: * the rollback verdicts it records are what the engine's hung-update watch * acts on, when CloudFormation never fails an update ECS rolled back * (FJL-901). * * Verdict semantics: `onECSComplete.success` reports the SUPERVISED * deployment's outcome. A circuit-breaker or CFN rollback that replaces the * supervised deployment is a failure verdict even though the service ends up * stable on the old revision, and `replacedBy` names which of them acted. */ export declare function createEcsDeploymentTail(deps: EcsDeploymentTailDeps): EcsDeploymentTail;