PostgreSQL Shadow Migration
A shadow migration imports copied Vorliq JSON state into a temporary PostgreSQL database, verifies parity, and then cleans up. It is rehearsal only. Production still uses hardened JSON as the source of truth.
Why It Is Safe
- The tools refuse database names that do not contain
shadowortest. - Production-looking hosts and database names are refused.
- The source JSON files are read only and are not updated or deleted.
- Blocks and transactions keep raw JSON so historical hashes and legacy payloads are preserved.
- The public runtime is not connected to PostgreSQL by this rehearsal.
- The PostgreSQL storage adapter is read in shadow mode only and write methods are blocked by default.
Run Locally
- Copy
database/.env.shadow.exampleinto your shell environment. - Start PostgreSQL with
docker compose -f database/docker-compose.shadow.yml up -d. - Install the optional Python PostgreSQL client with
python -m pip install "psycopg[binary]". - Run
python tools/run_shadow_migration_rehearsal.py --data-dir tests/fixtures/migration/sample_data --database-url "$SHADOW_DATABASE_URL" --check-adapter --output temp-shadow-report.json.
CI Fixture Data
CI uses deliberately fake data from tests/fixtures/migration/sample_data. The fixture includes a small valid chain, pending transactions, profiles, forum, governance, exchange, lending, treasury, registry, faucet, analytics, and incident records. It contains no production data, wallet private keys, admin tokens, SSH keys, or real credentials.
Parity Checks
- Record counts for migrated tables.
- Chain height and latest block hash.
- Block hashes by index.
- Confirmed and pending transaction totals and transaction IDs.
- Address balances for indexed addresses and treasury balance when present.
- Profile, forum, governance, exchange, lending, and treasury proposal counts.
- Secret-like text scans for private keys, passwords, admin tokens, SSH keys, and server paths in imported public rows.
- Adapter read parity for chain metadata, table counts, domain counts, confirmed transactions, and default write blocking.
Before Any Real Migration
A real production migration would require fresh verified JSON backups, repeated shadow parity passes, staging adapter smoke tests, a tested rollback plan, operator approval, and a separate cutover window. Until that happens, chain.json, pending.json, and the existing domain JSON files remain canonical.