Product details
The list, the two wizards, and the safety model that keeps real applies from happening by accident
Three mockups sit above. The first is the list of comparison runs that found drift, with the right rail showing the safety model and connection context. The second is the wizard that reconciles from an existing comparison — pick scope, preview, confirm, apply. The third is the wizard that does the whole thing in one shot from a saved Plan. The cards below walk through each one and the design choices that mean nobody accidentally writes 557 rows to production.
The drift list, the way an operator sees it
The first mockup is every comparison this project has run that came back with drift, with a warning triangle on the header so you know the page is about real differences and not summary stats. Each card packs the plan name, the masked source → target flow, the run date, and a copy-able hash on the left, and the +N green / ~N amber / -N red triplet plus a total drift count on the right. The 557-row spike sits in the middle of the list, with the smaller runs above and below it telling the story of how the plan diverged and how it eventually settled down.
The right rail is the safety model on the page
The first panel, Safety model, lists the four guarantees Cupcake makes about every apply — dry-run by default, project name typed for real apply, operator + selected rows in the audit trail, and the plan's column rules + expressions honored. The second panel, Connection context, names the connection the reconciliation will run against — plan name, source, target — so the operator can confirm at a glance that the right path is loaded. Quick stats roll the counters up: how many drift-bearing comparisons exist, how many have already been reconciled, how many reconciliations have completed, and when the last one ran.
The drift wizard — Step 1 SELECT
Click into one of the comparison cards and the four-step wizard opens on the SELECT screen. The card at the top names the comparison, its hash, and the drift summary (292 rows across 4 tables), then breaks it down by direction: SOURCE ONLY (+1, things only the source has — adds), DIFFERENT (~279, rows that exist on both sides but disagree — updates), TARGET ONLY (-12, rows only the target has — deletes). Below that, the operator picks between 'Apply all drift' (use every drift row from every table) and 'Selected tables' (apply only the checked tables in the list underneath). Each table row shows its own +N ~N -N breakdown so scope is never guessed.
Steps 2–4 — PREVIEW, CONFIRM, APPLY
PREVIEW dry-runs the selection and prints exactly what would be written — table by table, row by row — without committing anything. CONFIRM is the safety phrase: the operator types the project name back to flip the apply from dry-run to real. APPLY does the writes, streams progress, and lands a receipt in the Reconciliation history below the list (the table that reads 'No reconciliations have been run on this project yet' in the screenshot). Every step is reversible up until APPLY, and the audit trail captures every step regardless.
Reconcile from plan — when you don't have a comparison yet
The third mockup is the shortcut. Sometimes you don't have a Compare run sitting in the list — you want to reconcile a plan right now, end to end. The 'Reconcile from plan' wizard collapses two pages into three steps: pick the plan, pick the path, confirm, apply. The path choice is the interesting part: Sync now applies each drifty table synchronously and returns when done (best for small fixes), or Run as repair job queues an async ReplicationJob you watch via the event stream (best for the days when the drift is 557 rows or more). The optional row cap forwards to the comparison run that fires under the hood.
Why Reconcile is its own page and not a button on Compare
Compare finds drift. Reconcile fixes it. Separating them is on purpose — discovery and remediation have different blast radii, different audit needs, and different people allowed to do them. The Safety model panel is what makes the separation real: anyone on the team can run Compare any time, but Reconcile defaults to dry-run, asks for a typed confirmation, and writes every apply to the audit trail. That gap is the difference between 'the system showed us drift' and 'someone changed production data.'
Dry-run by default, real apply by confirmation
Every run defaults to dry-run mode — Cupcake walks through exactly what it would write but commits nothing. To flip to a real apply, the operator types the project name back. That single piece of friction is why 'I clicked the wrong button' isn't a story this page tells.
Per-table or per-row control
The drift wizard lets you reconcile the entire comparison or just the tables you've checked. Every selection shows its own +N ~N -N breakdown so the operator knows exactly what's being applied before the preview, and exactly what was applied after the audit trail.
A receipt for every reconciliation
Real or dry-run, the result lands in the Reconciliation history below the list — operator, plan, scope, row counts, outcome. It's the answer to 'who fixed it, when, and what did they change?' that audit calls always end up asking.