/** * NS propagation gate — the bounded public-recursive-resolver check between * the `phase: "zone"` and `phase: "full"` deploys of a delegated child domain * (D8; dev-substrate design R2 refinement). A bare `GetHostedZone` proves the * child zone EXISTS; only a public resolver proves the parent's delegation * has PROPAGATED — and issuing a DNS-validated certificate before then hangs * ACM until CloudFormation rolls back (~1 h). * * Fail-closed on bound-expiry with `delegation_unreachable` (the design's 422 * vocabulary), naming the retry command and the manual-NS option (Case-3 * externally-owned parent) per the fail-closed ADR. */ import { type Result } from "@fjall/generator"; import type { DeployCallbacks } from "../../types/callbacks.js"; import { DomainDelegationError, type PublicDnsResolver } from "./types.js"; /** ~2 minutes of polling by default: 12 attempts x 10s interval. */ export declare const NS_PROPAGATION_DEFAULT_MAX_ATTEMPTS = 12; export declare const NS_PROPAGATION_DEFAULT_INTERVAL_MS = 10000; export interface NsPropagationGateParams { /** Fully-qualified delegated child zone, e.g. `dev.example.com`. */ zoneName: string; /** * The child zone's authoritative name servers, when the caller knows them * (domain-stack outputs). Supplied ⇒ a public NS answer must overlap this * set — an answer pointing at a DIFFERENT NS set is a STALE delegation (a * prior zone's name servers still answering), exactly the state that hangs * certificate validation, so the gate keeps polling rather than passing. */ expectedNameServers?: readonly string[]; maxAttempts?: number; intervalMs?: number; /** Injectable resolvers (tests use fakes); defaults to 1.1.1.1 + 8.8.8.8. */ resolvers?: readonly PublicDnsResolver[]; /** Injectable clock (tests make the interval instant). */ sleepFn?: (ms: number) => Promise; abortSignal?: AbortSignal; callbacks?: DeployCallbacks; /** * The command the cure names for resuming after propagation completes. * Phase-3 surfaces pass their own spelling; the default is the CLI verb. */ retryCommand?: string; } export interface NsPropagationVerdict { /** The name servers the succeeding resolver returned. */ nameServers: string[]; /** 1-based attempt count at success. */ attempts: number; /** Which public resolver observed the delegation. */ resolverAddress: string; } /** * Poll the public resolvers until the child zone's NS delegation is visible, * up to `maxAttempts` x `intervalMs`. Read-only; safe to re-run any number of * times. Expiry returns `delegation_unreachable` — the zone phase stays * deployed and retained, so the cure is a re-run (which resumes at this gate), * never a rollback. */ export declare function waitForNsPropagation(params: NsPropagationGateParams): Promise>;