# Repair — A throwaway test run rewrote our live database

A flowingkhaos fix · monitoring · updated 17 Oct 2026
Source: https://flowingkhaos.com/fixes/worktree-run-migrated-production-database/repair

Three changes, landed on 6 and 7 October 2026.

**1. A database per run.** A script, `run-db.sh up`, pulls `postgres:17.11-alpine`, starts a container named after the run, waits for the TCP port to answer, and writes the connection string to `db.env` in the run's artifacts folder. `run-db.sh down` removes the container and its volume. Vault commits cfa561f, 14a06ab and eb25463.

**2. Export before anything.** The validate node's first line now exports `db.env` into the environment. Bun and Next's env loader never override a variable that is already set, so the file in the checkout loses every time. We proved it with `loadEnvConfig('apps/cms')` after the export: the worktree's `.env.local` could not win.

**3. A second net.** A Claude Code mod watches every shell call the agent makes. A call that could reach the production database is held and the operator is asked; when there is no operator (a headless run) it is refused. It is a guard, not the fix: the fix is that the gate no longer knows the production address.

**What it costs, measured on 7 October, five rounds**

| Step | Time | How often |
| --- | --- | --- |
| up (pull, start, wait for TCP) | 12.8 to 14.7 s | once per run, beside the research nodes |
| load `db.env` | about 0 | every iteration |
| full migrate on the empty database | 72 s | once per run; 55 of 55 migrations |
| down | 0.9 s | once per run |

The up step overlaps work that runs anyway, so the wall clock of a run barely moves. The 72 seconds are real and paid once.
