/** * Teardown planning (#1222) — the enumeration half of * `chant lifecycle teardown `. * * Answers one question: which live resources carry THIS project's ownership * marker for THIS environment? Selection is marker-scoped by construction — * managed-by present, stack equal to the project's `ownership.stack`, env * equal to the argument — so a foreign stack's resources, another env's * resources, and unmarked resources are out of scope by shape, not by * filtering discipline someone has to remember. * * Stateless: live markers only. No build, no snapshot, no ledger — the * ownership record lives on the cloud resource (see ../ownership.ts), and this * module reads it back from there. * * Two paths per lexicon: * - the `teardownOwned` capability, where the lexicon enumerates its own * would-delete set (and can use a read shaped for deletion — aws's * stack-level path, k8s's prune selector); * - a fallback over `describeResources` + the {@link ResourceMetadata.marker} * field (#1222 PR 1), for lexicons that have not implemented the capability * yet. Best-effort: a lexicon whose thin read only resolves declared names * returns nothing here, which the plan reports as a skip, not as clean. * * Whichever path ran, core re-checks every candidate's marker and drops * mismatches — an implementation bug can narrow the set, never widen it. * * The execution half is {@link executeTeardown}: it drives each lexicon's * `executeTeardown` capability over the planned set, then runs one bounded * retry pass over the failures. Both halves are exported as functions — * #1224's test-env harness calls them in-process, not only through the verb. */ import type { ObservationLexicon, TeardownCandidate, TeardownHole } from "../lexicon.js"; /** One would-delete row in a teardown plan, attributed to its lexicon. */ export interface TeardownPlanEntry extends TeardownCandidate { lexicon: string; } /** One hole in a teardown plan (#1089), attributed to its lexicon. */ export interface TeardownPlanHole extends TeardownHole { lexicon: string; } /** The plan `chant lifecycle teardown ` prints and #1224 consumes. */ export interface TeardownPlan { environment: string; /** The project's ownership stack — the identity everything was selected on. */ stack: string; /** The would-delete set. Every entry's marker equals `{ stack, env: environment }`. */ entries: TeardownPlanEntry[]; /** What could not be read (#1089). A plan with holes is incomplete, not clean. */ holes: TeardownPlanHole[]; /** * Lexicons that took part in neither path — no `teardownOwned`, no * `describeResources`. Reported so "nothing to delete" can never quietly * mean "nobody looked". */ skipped: string[]; } export interface PlanTeardownOptions { /** The environment being torn down — the marker env to select on. */ environment: string; /** This project's ownership stack (`ownership.stack` in chant.config). */ stack: string; plugins: ObservationLexicon[]; /** Deployed stack name, for a multi-stack project. */ deployedStack?: string; /** Region that stack is deployed in. */ region?: string; /** * Every deployed stack a multi-stack project declares (`stacks` in * chant.config), for a lexicon whose teardown is stack-shaped (aws * enumerates and deletes whole stacks). Forwarded to `teardownOwned` / * `executeTeardown` as `stacks`. */ deployedStacks?: Array<{ name: string; region?: string; }>; } /** * Enumerate what `chant lifecycle teardown ` would delete. Read-only — * this function never deletes and never will; execution composes on top of the * plan it returns. */ export declare function planTeardown(opts: PlanTeardownOptions): Promise; /** One planned entry's fate after execution, attributed to its lexicon. */ export interface TeardownOutcomeEntry extends TeardownPlanEntry { /** * `skipped` is core's verdict for a candidate whose lexicon implements no * `executeTeardown` yet; the other three come from the lexicon (see * {@link TeardownOutcome}). */ outcome: "deleted" | "failed" | "not-prunable" | "skipped"; /** The error for `failed`, the reason for `not-prunable`/`skipped`. */ detail?: string; /** True when this final outcome came from the bounded retry pass. */ retried?: boolean; } /** What `chant lifecycle teardown --yes` prints and #1224 consumes. */ export interface TeardownReport { environment: string; stack: string; /** The plan that was executed — holes and skipped lexicons included. */ plan: TeardownPlan; /** One row per planned entry. Never fewer: silence is never success. */ outcomes: TeardownOutcomeEntry[]; /** Lexicons whose candidates were skipped for lack of an `executeTeardown`. */ unimplemented: string[]; } export interface ExecuteTeardownOptions extends PlanTeardownOptions { /** * A plan already computed (the one just shown to the user). Recomputed from * a fresh live read when omitted. */ plan?: TeardownPlan; } /** * Execute a teardown: delete every planned candidate through its lexicon's * `executeTeardown`, then retry the failures once. Per-lexicon ordering only — * each lexicon deletes its own set in the order its target requires (k8s * deletes namespaces last, fly deletes apps last); there is no global * reverse-dependency ordering in v1, the bounded retry pass covers the * cross-lexicon cases it would. * * Every planned entry comes back with an outcome. A lexicon that enumerates * but implements no execution reports its candidates as `skipped` — loudly, * never as clean. Failures that survive the retry stay `failed` in the * report; nothing here ever swallows one. */ export declare function executeTeardown(opts: ExecuteTeardownOptions): Promise; //# sourceMappingURL=teardown.d.ts.map