rehearse against the real shape, not an empty one
Structural changes had accumulated on the mainline and had never been applied where the data lives. Applying them there is a one-way door, so the question worth answering first is not whether the history replays but whether it applies to a store that already holds things.
Those are different questions. A chain replayed into an empty store proves the history is well formed and proves nothing about existing rows, and the failures that hurt come from existing rows: a value that no longer fits a narrowed rule, a column that arrives unpopulated, a constraint satisfied only by data written by somebody who never heard of it.
So the rehearsal cloned the shape of the live store into a throwaway instance — the same objects and the same record of what had already been applied — and did the same for a second business to confirm the two shapes matched. Then the pending steps ran there. The findings were the useful part: no conflicts, a strictly additive result, every previously applied step still matching the file now in the repository, and a rollback followed by a re-apply that worked.
One step was recorded as not separately reversible, because later objects depend on it; the runbook says so rather than offering a rollback that would break the store. And one pending step was allowed to reach the live store only after it landed on the mainline, which put a structural change in a defined order between two workstreams instead of in whichever finished first.
Cost: a rehearsal that must be rebuilt whenever the live shape moves.
What it proves: the team rehearses against the thing being changed, and writes down what must not be undone.
drawn from: commit cluster — production-shape dry run and apply gate
Every note carries a codename and one idea. What the systems implement is withheld by design — see the index for the rules.