4.0 KiB
Disposable clone migration gate
npm run db:migrate:clone applies the release's normal ordered migrations to an existing,
disposable PostgreSQL clone. It is the migration step for a restored production dump before an
immutable release is eligible for activation. It never creates, restores, drops, audits, or
activates a database.
Hard target contract
The runner refuses to open a connection unless all of these conditions hold:
DB_HOSTis explicit loopback (127.0.0.1,::1, orlocalhost) or the standard local Unix socket directory/run/postgresqlor/var/run/postgresql;DB_NAMEstarts withmonerogue_,wownerogue_, orwowngeon_and contains a complete underscore-delimitedclone,restore, orcanarytoken;- the name contains no live marker beginning with
prd,prod,production,live,mainnet,master,primary,current, oractive; CLONE_MIGRATION_EXPECT_DATABASEexactly equalsDB_NAME;CLONE_MIGRATION_CONFIRMexactly equalsMIGRATE_DISPOSABLE_CLONE:<DB_NAME>;DB_PORTandDB_USERare explicit,DATABASE_URLis absent, and the process receives no command-line arguments.
After connecting, the runner checks PostgreSQL's current_database() before any DDL. It then calls
the same DatabaseManager.runMigrations() used by application startup: lexical filename order,
the schema_migrations ledger, and one transaction per newly applied file. Finally, it requires the
ledger to equal the complete repository migration manifest, in order, with no missing or extra
entry. The manifest is discovered from the candidate release and must be contiguous from 001; the
current floor is migration 043. A successful current release reports:
clone_migration_status=ok
database=monerogue_restore_20260721t220048z_28d513b29b36
migration_count=43
latest_migration=043_durable_solo_restart_snapshots.sql
Invocation
Create and restore the clone with the reviewed backup procedure first. Keep the target variables in
a protected operator-owned environment file and database credentials in a mode-0600 PGPASSFILE;
do not type a password, connection URL, or target as a command argument. For example, the inherited
non-secret target environment is:
DB_HOST=127.0.0.1
DB_PORT=5432
DB_NAME=monerogue_restore_20260721t220048z_28d513b29b36
DB_USER=monerogue
PGPASSFILE=/run/wowngeon/clone-migration.pgpass
CLONE_MIGRATION_EXPECT_DATABASE=monerogue_restore_20260721t220048z_28d513b29b36
CLONE_MIGRATION_CONFIRM=MIGRATE_DISPOSABLE_CLONE:monerogue_restore_20260721t220048z_28d513b29b36
Database names use lowercase letters, digits, and underscores only. Normalize a release ID into a
separate safe tag rather than copying a hyphenated artifact ID into DB_NAME.
Load that protected environment through the reviewed service/wrapper, change into the extracted
candidate's src directory, and run only:
npm run db:migrate:clone
Do not append -- arguments. The runner never logs host, role, password, connection URL, or
PGPASSFILE contents. DB_PASSWORD is supported only for an already-protected inherited service
environment and is kept in memory; PGPASSFILE is preferred.
Required follow-on gates and limits
Run scripts/deploy/financial-audit.sql and the restored-data constraint validation gate against
the same clone after migration. Compare the result with the pre-migration audit, then test the
candidate and predecessor against the migrated clone as required by the fleet runbook.
This runner does not prove that a database with a disposable-looking name is operationally disposable, does not prevent another application process from connecting, and does not acquire an activation-wide drain lock. The operator must create the clone from the intended fresh dump, keep it outside public service configuration, and destroy it separately after the release decision. A successful result authorizes only the next audit/test gate; it does not authorize a symlink switch, wallet action, payout, or traffic restoration.