Shadow Execution
Shadow execution settles what static review cannot: what actually happens when this runs? From the approval screen, Shadow run provisions a disposable twin of the target, applies the pending script, diffs the schema before and after, and tears the twin down, surfacing the real effect and the real error without touching the target.
Pipeline
- Provision, a synthetic twin on the target's server (or a dedicated sidecar, per deployment).
- Build, source schema rebuilt into the twin with planner statistics for fidelity. No production rows by default.
- (Optional) Sample, Run with sample data copies a bounded random sample of the touched tables (and FK parents) so data-dependent migrations (backfills, UPDATE/DELETE) operate on representative data and report realistic counts. Opt-in per run because sampled rows are real data.
- Run, the script executes in a transaction under statement and lock timeouts; per-statement success/exact error, duration, and rows affected are recorded.
- Diff, twin schema compared before vs. after (the Flight Recorder diff engine), surfacing added/removed/altered objects.
- Teardown, the twin is always dropped; a background sweeper force-drops any twin outliving its run.
Honesty Contract
A shadow run executes against a schema-faithful, data-sampled twin. It proves the migration applies cleanly and what it changes structurally; it does not prove behavior at full production volume or on real data distributions. Every result carries this caveat, because a dry run implying fidelity it lacks is worse than none. On failure the panel shows the exact SQL error, the single most valuable output.
Safety Model
The source is only ever read, schema introspection and, when sampling, SELECTs on a session pinned read-only, so the feature physically cannot write to it, plus the server-level create/drop of the twin. The script itself only ever touches the throwaway twin. Twin credentials are ephemeral and never stored; no sampled row values are persisted to the record (counts only). Supported on PostgreSQL and MySQL/MariaDB; other dialects report unavailability rather than an empty result. On MySQL the empty twin has no planner statistics (no fake-stats import as on PostgreSQL), so sample data when realistic plans matter. Twin mode, timeouts, sample size, and sweep age are documented under Configuration.