## TL;DR
The dev ini pointed at (or configured for) the wrong database, so a dev-configured alembic ran against production. Assess what ran and with what settings, then separate configs per environment: one ini per environment (or one ini reading the URL from the environment), a wrapper that selects by explicit --env flag, and a guard that refuses dev-configured runs against production hosts.

## The query

```text
agent ran alembic with the dev alembic.ini against the production database
```

## Use this when

- Alembic ran with dev alembic.ini against production
- Wrong ini file targeted the wrong database
- Need per-environment alembic configs
- An agent used the dev config on prod

## Not for

- The right config failing on prod (fix the migration)
- A dev ini used on a dev database (that is its job)
- Connection-string confusion without ini involvement (guard the URL directly)

## Steps

### 1. Assess what ran and under what settings

Read the dev ini: which sqlalchemy.url did it resolve to, and what settings differ from prod (echo, pool sizes, transaction settings)? Check the state table on the affected database to see which revisions applied.

Expected output: the exact database hit, the revisions applied, and any dev-only settings (like verbose echo or aggressive pooling) that touched prod.

### 2. Contain and reconcile

If unexpected revisions applied to prod, reconcile the schema and the history (inventory, hand-apply or stamp, as with any out-of-place migration). Rotate any credentials the dev config exposed. Expected output: prod's schema and history are consistent and deliberate again.

### 3. Separate configs per environment

Create alembic.prod.ini (and staging), or keep one ini that reads the URL from the environment and nothing else. No ini file should contain a production URL as a default a dev command can pick up accidentally.

Expected output: there is no single file that a bare alembic command can load and hit prod with.

### 4. Add the env-selecting wrapper

The agent runs migrations through a wrapper requiring --env, which selects the ini and prints the resolved target for confirmation. The wrapper refuses --env prod without an additional explicit confirmation flag.

Expected output: running alembic "the normal way" cannot reach prod; reaching prod requires two deliberate flags.

### 5. Make the dev ini unable to reach prod structurally

The dev ini's URL should resolve to a local database only (YOUR_HOST, or a socket). If the dev config cannot address prod at the network level, the wrong-ini mistake becomes a connection error, not an incident.

Expected output: the entire class of mistake degrades to "connection refused".

## Tool compatibility

alembic 1.x. The per-environment config pattern applies to any ini-based tool.

## Variant phrasings

### alembic dev ini against production

Steps 1 and 2: assess what ran, reconcile prod.

### per-environment alembic config

Step 3: one ini per environment, no prod URL as any default.

### prevent alembic hitting wrong database

Steps 4 and 5: env-selecting wrapper plus a dev ini that cannot route to prod.

## Why it happens

Alembic resolves its database from the ini file, and a bare alembic command loads alembic.ini from the current directory: whatever that file says is the target. When the dev ini is the default and it can address prod (via an env var someone exported, or a URL someone pasted), the tool does exactly what it was configured to do. The bug is a configuration that makes the wrong target reachable by default.

## Edge cases

- Env-var-driven URLs are the usual vector: the ini reads sqlalchemy.url from DATABASE_URL, and the agent's shell had prod's. Fix the shell hygiene too, not just the ini.
- A wrapper the agent can bypass with an env var is decoration: the prod confirmation must be a separate explicit flag.
- Audit other ini-driven tools in the agent's reach (pytest configs, deploy scripts): the same default-config hazard usually exists in more than one place.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst__iZwFiI1B4Z7LA4dYS01tQ
