Skip to Content
How Bahama worksState, plans, and safety

State, plans, and safety

Infrastructure work becomes risky when you or your coding agent cannot tell intent, live resources, credentials, and operational history apart. Bahama keeps each kind of information in a separate place with a clear owner.

Four different kinds of state

LocationOwnerCommit it?What it contains
bahama.yamlYou and your agentYesIntended application, environments, resources, and bindings
bahama.lockBahama CLIYesVerified provider accounts, durable resource identities, and applied binding edges
.bahama/Bahama CLINoLocal plans, operation receipts, and the active-operation lock
Provider credential storesThe provider or Bahama CLINeverLogin sessions and tokens

Live provider state is the final authority for whether a resource actually exists and is healthy. The lock tells Bahama which live resource belongs to this repository; it is not a cached copy of every provider attribute.

bahama.yaml records intent

The manifest is meant to be read and edited by both you and your agent. It answers questions such as:

  • Which framework does this application use?
  • Where should it run?
  • Which database does it need?
  • Which produced values should reach which environments?

It never contains resolved provider IDs or secret values. The schema rejects common ID-shaped fields rather than silently accepting a dangerous guess.

bahama.lock records verified identity

The lock is written only after a provider operation passes its live postcondition. It records durable identities, provider account boundaries, and which binding edges have already been applied.

Commit the lock alongside the manifest. That lets a future agent session—on this machine or another one—reconnect to the same verified resources without relying on provider defaults, local link files, or chat history.

Do not hand-edit it. If the lock is wrong, use the relevant Bahama recovery flow so live state can be checked instead of manufacturing an identity.

.bahama/ is local recovery evidence

The .bahama/ directory contains:

  • immutable compiled plans;
  • an append-only operation journal; and
  • a lock that prevents two mutating operations from running at once.

It is machine-local and should remain gitignored. Receipts help resume an unfinished operation, but they do not overrule current provider state.

Plans are exact and reviewable

bahama plan reads the manifest, lock, selected provider accounts, relevant live resources, and consequential provider configuration. It then produces a content-derived plan ID.

The same validated inputs produce the same plan. Change the manifest, lock, migration files, planned account, or protected provider configuration and the old plan is no longer valid.

Source-code edits are different. A deployment plan authorizes the deployment shape; apply packages the source present at execution time and records what was actually shipped.

Routine and consequential work

Bahama classifies every step centrally.

Common consequential changes include:

  • creating or adopting a resource;
  • selecting or changing a provider account;
  • applying a database migration;
  • making a first deployment;
  • connecting a secret for the first time;
  • feeding an existing variable from a different source; and
  • changing provider configuration that can alter production behavior.

Routine work preserves the established graph. Examples include checking an existing resource, redeploying code to the same verified environment, or rotating a value along an unchanged binding edge.

Unknown mutations are consequential by default. If a provider forgets to describe an effect, the omission does not become an approval bypass.

Approval belongs to the person

When a plan contains consequential steps, Bahama reports approval required. Your agent should show you the steps, reasons, and provider accounts before it runs:

bahama apply plan_7f4c9b21a3d0 --approved

--approved means a person reviewed that exact plan. A general request such as “finish the deployment” is not permission to create unexpected resources, migrate a schema, or reconnect production to a different database.

An all-routine infrastructure plan can be applied without --approved. bahama deploy can auto-apply only when every compiled deployment step is routine.

Success requires a live postcondition

Each execution step states what must be true afterward. A driver performs the operation, checks the provider, and reports success only when that postcondition is verified.

Examples include:

  • the new project exists under the planned account;
  • the database accepts connections;
  • the migration ledger contains the approved checksums;
  • the environment-variable name exists at the destination; or
  • the production URL responds successfully.

This is why Bahama may report a failed deployment even when a provider command exited zero: publication without a healthy live result is not completion.

Interrupted work can resume

If apply stops halfway through, read the failure and its recovery guidance first. When the same unfinished plan remains valid, run the same apply command again.

Bahama rechecks verified receipts, skips completed postconditions, and resumes at the first unfinished step. Secret values are re-derived in the new process; they are never stored in the journal for convenience.

Repository identity protects copied projects

The lock records which repository it belongs to. If a template or fork carries someone else’s lock, planning stops with decision required rather than deploying over the original project.

For an intentional new copy, bahama detach --approved removes the complete local lock while leaving the manifest and all remote resources unchanged. The next plan resolves a fresh stack under the selected accounts.

Detach is not a general repair command. If one provider resource is missing, keep the lock so Bahama can preserve the healthy identities and plan a targeted replacement.

Secrets are values, not serialized state

Supported secret capabilities move through the engine as opaque references. Raw values are registered with the redactor before ordinary provider code can observe them and are used only at the destination step.

Your agent should never ask you to paste a secret into chat. Neither of you should place one in the manifest, lock, plan, receipt, log, screenshot, or browser-visible environment variable. If a secret appears in output, stop sharing the output and rotate the value at its provider.

Last updated on