Change management

Plan, approve, apply, verify: how Ahena changes your providers

The change lifecycle in Ahena: plans per environment, the SAFE to MANUAL classifications, who approves what in production, and how applies are checked.

Published Updated 6 min read

In short

Every change Ahena makes at a provider is planned first, for one environment. Each operation is classified SAFE, CONFIRMATION_REQUIRED, BILLABLE, DESTRUCTIVE or MANUAL. SAFE changes apply without asking; anything else needs a person, and changes that matter (anything beyond SAFE in production, billable or destructive anywhere) are approved only in the signed-in dashboard. Ahena never applies MANUAL steps. Apply re-checks each provider against the plan you reviewed, and verification reads every change back.

The lifecycle

Ahena never changes a provider in one step. Every change, whether you asked for it, Doctor proposed it as a fix, or an AI agent suggested it, goes through the same sequence:

intent → plan → approval → apply → verify → generate → doctor

Intent is what ahena.config.ts declares. A plan is what has to change at each provider to match it. Approval is a person agreeing to that plan, at the level the change calls for. Apply makes the changes, verification reads them back, and Doctor checks the result. This guide walks through each step and the rules that decide who has to approve what.

ahena plan                    # store a plan per environment with changes
ahena apply pln_…             # review, approve, apply, refresh ahena.lock
ahena apply -e production     # plan and apply in one step

What a plan contains

A plan covers one environment and every provider in it. It has two kinds of entries:

  • Provider operations, from each provider's own read-only plan: what ahena.config.ts declares, plus the email DNS records a Cloudflare zone needs. Each carries its classification and any known cost.
  • Manual operations: steps only you can do, such as Doctor's manual fixes or providers to connect, with instructions. Ahena never marks them done.

Planning is read-only. Plans are stored and visible in the dashboard (Project → Plans) and audited. A new plan for the same environment replaces earlier ones nobody has approved yet, which become CANCELLED; approved plans are kept. A plan with nothing to change and nothing for you to do is APPLIED as soon as it's made.

The five classifications

Every operation is classified by what it can do to you if it's wrong:

ClassificationMeaningExamples
SAFEApplied without asking.Asking Resend to re-check a domain's DNS; generating code that keeps your edits
CONFIRMATION_REQUIREDReversible and not billed, but it changes something: a person confirms it.CORS on an R2 bucket, DNS records, Supabase auth URLs, Stripe webhooks, products and prices, Resend domains and webhooks, Firebase app registration
BILLABLEMay be billed to your provider account. Needs its own approval.Creating an R2 bucket
DESTRUCTIVECan't be undone. Needs its own approval.Approved like billable changes: separately, and in the dashboard in every environment
MANUALA step only you can do. Ahena never applies it.Connecting a provider; a fix Doctor can explain but not make

Billable and destructive changes are always asked about separately. In scripts, --yes covers CONFIRMATION_REQUIRED changes only; billable and destructive ones also need --allow-billable. And, as the next section explains, some changes need the dashboard no matter which flags you pass.

Production rules

A change "matters" when it isn't SAFE in production, or is billable or destructive anywhere. Changes that matter are approved only in the Ahena dashboard, signed in. The CLI's token and AI agents can ask for approval but never give it, even with an admin's token.

EnvironmentSAFECONFIRMATION_REQUIREDBILLABLE / DESTRUCTIVE
Production (effective)AppliedDashboardDashboard
Any otherAppliedApprove in the CLI (or the MCP client's prompt)Dashboard

"Production" is the environment's effective kind. It's production when its kind is production, or when any of its connections holds a live credential such as a Stripe sk_live_ key. A "development" environment with a live Stripe key gets every production rule, and the plan and approval pages say why. The check runs when a change is approved and again when it's applied, so connecting a live key after approving from the CLI doesn't let a change through.

Roles matter too. Developers can approve changes outside production. Production changes, and billable or destructive changes anywhere, need an owner or admin. Ahena checks this inside its core services, so the dashboard, the API, the CLI and the MCP server can't disagree.

Approving a plan

ahena apply asks once for the plan, and separately for anything billable or destructive. A provider's changes are approved together, because they can depend on each other: CORS on an R2 bucket only works once the bucket that the same plan creates exists. Leaving out a billable change holds back every change for that provider, and the CLI says so before it asks anything:

Left out: Cloudflare's changes. Approve the billable change to apply this provider's changes (Create R2 bucket leo-uploads (production)): pass --allow-billable.

Other providers in the plan still go ahead. For changes that matter, the CLI then opens the dashboard and waits:

These changes need your approval in the Ahena dashboard: https://app.ahena.io/approvals/apr_…
  Waiting for your decision in the browser. Nothing is applied without it.
✓ Approved in the dashboard.

The approval page lists the organization, project and environment, every operation with its classification and cost notice, and who asked: your terminal or an AI agent. The summary is built by Ahena from its own re-plan, never from text the client sent. Declined or expired (after 60 minutes): nothing is applied, and the plan is cancelled. In scripts, --no-wait prints the link and exits with code 4; once you've approved, ahena apply pln_… applies the approved operations without asking again, within 60 minutes of the approval.

Apply: what you reviewed is what runs

Providers are applied one after another, Cloudflare first, since other providers verify DNS against it. Before applying, each provider re-plans and compares a fingerprint of its state with the plan you reviewed. If the provider changed in between, nothing is applied for it, and the operation fails with "changed since you reviewed". A dashboard approval for a direct apply covers exactly one environment, provider, fingerprint and set of actions, and is used once.

Only one apply runs per environment at a time, so a retry can't race a slow first run into creating something twice. If Stripe fails after Cloudflare succeeded, the plan ends PARTIALLY_APPLIED with each operation's outcome. Ahena doesn't delete what succeeded to fake atomicity. A provider error is recorded as failed with the provider's reason, and the CLI prints why, where, the impact and whether a retry fixes it.

The same rules apply to every way of changing a provider: ahena apply, ahena configure, ahena diff --apply, ahena doctor --fix, ahena drift --fix, the dashboard, and the MCP server's tools.

Verify, and what you see afterwards

After every write, Ahena reads the provider back and compares what it finds with what was planned. Each operation ends verified, applied but unverified, failed, unknown, skipped or manual, and the plan's status follows from its operations without rounding up: APPLIED only when every operation that ran was verified. Why that matters, and how unknown outcomes are recovered, is the subject of Why a 2xx response isn't verification.

Afterwards, Ahena refreshes ahena.lock for the providers it changed, so its own changes aren't reported as drift, and everything is in the audit log: approval.request, approval.approve or approval.decline, approval.use, and plan.approve with how it was approved. Then run Doctor to see the result in context:

ahena doctor -e production

Try it on your own stack

Start free with one project. Connect the providers you already use, run Doctor, and see the plan before anything changes.