Expand/contract repair
Safe
No supported incompatibility was detected under the conditions tested. This is not a universal safety guarantee.
Keeps email, adds email_address, syncs both with a trigger. The destructive step is deferred.
Recorded example: genuine engine output generated Sat, 24 Oct 2026 18:30:04 GMT from the committed fixture. Run it again live below.
Baseline schema
Proposed schema
Previous versionshop-v1
2/2 test files passno database errors
2/2 test files passno database errors, identical in all 2 runs
Current versionH-valid-repair
Not needed: ordinary CI covers this
1/1 test files passno database errors
The outlined cell is the compatibility question. The verdict comes only from it, compared against the cell to its left.
Next step
Proceed with normal review. Keep the old application's tests meaningful; SAFE only covers what they exercise.
Starts a throwaway PostgreSQL and runs the full experiment, usually in under 15 seconds.
Schema changes
2 of 2 risk-bearing schema change(s) were exercised by the old application's tests in the control run.
| Change | Risk to old statements | Exercised by previous version |
|---|---|---|
| Column customers.email_address added (text) | inert | Not required |
| Index customers_email_address_key added on customers | breaking | Yes, 2 statements in test/customers.test.js, test/orders.test.js |
| Trigger customers_sync_email added on customers | behavioral | Yes, 2 statements in test/customers.test.js, test/orders.test.js |
Runs
Proposed migration: 002_rename_email.sql · PostgreSQL 16.15 (Debian 16.15-1.pgdg12+2) · gate does not block (exit 0)
| Run | Migrations | Test files | Database errors | Statements logged |
|---|---|---|---|---|
| control (old app × baseline schema) | 1/1 | 2/2 pass | 0 | 7 |
| candidate #1 (old app × proposed schema) | 2/2 | 2/2 pass | 0 | 7 |
| candidate #2 (old app × proposed schema) | 2/2 | 2/2 pass | 0 | 7 |
| current app × proposed schema (context) | 2/2 | 1/1 pass | 0 | 2 |
Download this report: JSONMarkdownJUnit XML
What this result does not cover
- Performance / lock-time analysis (out of scope).
- Skewcheck only observes code paths that the old application's tests execute; untested paths are reported as coverage gaps, not as safe.
- Coverage is identifier-level: a statement "touches" a changed object when it names the table (and column, or uses *). It is not a SQL parser.
- Correlation between an error and a schema change uses a fixed set of deterministic rules (R1–R6). Anything else is reported as ADVISORY, never UNSAFE.
- Performance, locking and migration runtime on production-sized data are not evaluated.
- Test files of one run share a database and run sequentially; ordering effects are identical across runs but are not isolated.
- Data-only migration effects are detected only when a test asserts on the affected data.