/** * Assembly digest — a deterministic fold over the per-stack template hashes that * the detection pipeline already computes (TemplateHashService). Bound into the * approval token and re-checked before apply, it is the secret-free guarantee * that the plan the approver saw is the plan that executes (no TOCTOU): if any * stack's synthesised template changed between plan and apply, the digest * diverges and the gate refuses the stale token. * * The optional {@link DeployScope} folds the RESOLVED deploy behaviour into the * digest as well: the exact stack subset the deploy loop will deploy and * whether an image build/push will run. A token minted under `--infra-only` * then refuses as `superseded` on a full apply (and vice versa) — scope flags * are part of what the approver sanctioned, not just the templates. Scopeless * calls (domain deploys, which always `cdk deploy --all` and never build) * produce the legacy digest byte-for-byte. */ /** * The resolved deploy scope bound into the digest. Derived from the SAME * values the deploy loop consumes (`getStackNamesToDeploy`, * `willRunDockerBuild`) — never re-derived from raw option flags. */ export interface DeployScope { /** The exact stack names the deploy loop will deploy (any order). */ readonly stacksToDeploy: readonly string[]; /** True when the pipeline will build and push application image(s). */ readonly imageBuild: boolean; } /** * Fold the stack-name → template-hash map (and, when supplied, the resolved * deploy scope) into a single sha256 hex digest. Entries are sorted by stack * name so the digest is independent of map order, and each pair is framed * with a NUL separator so `{ab, c}` cannot collide with `{a, bc}`. The NUL * pair separator is the SHIPPED wire derivation — changing it invalidates * every outstanding token and stored digest, so the scopeless legacy pin in * assemblyDigest.test.ts locks it byte-for-byte. Scope lines carry a * `scope:` prefix (CloudFormation stack names cannot contain `:`), appended * after the hash lines, with the stack subset sorted for order-independence. */ export declare function computeAssemblyDigest(stackHashes: ReadonlyMap, scope?: DeployScope): string; /** * The short head of the digest embedded in the approval token wire format * (`signPlanToken` reuses the planToken shape). The full digest stays in the * durable plan record; the token carries only enough to bind it. */ export declare function digestHead(assemblyDigest: string): string;