I3.09.1clean rollback restoredesign

Rollback must restore the pre-failure UI, not leave a pending ghost

Aliases: pending ghost · leftover sending · restore snapshot

What it is

An optimistic write fails. The screen has to return to the world of the frame before the press: the heart unlit, the comment absent from the list, the switch on its original side. Rollback’s moment is the beat the authority refuses; the act is peeling the optimistic layer off, not pasting “failing” or “sending” on top of it so it stalls halfway. What remains halfway is a transitional trace — a greyed comment, a half-lit heart, a send arrow that spins forever. The trace is neither success nor pre-failure. Nothing can be done on it.

This leaf is which state the UI is placed in. That the failure must be spoken is another obligation; here the placement itself has to be clean.

Why it happens

Optimistic update inserts an extra state in the UI machine: locally committed, not yet authorised. Success promotes that state to confirmed; failure must erase it so the machine sits in the last legal pre-failure state. If erase is implemented as “patch this state with failure”, the machine gains a legal state the product never designed — a half comment, a half heart. Later interaction (tap again, delete, quote) lands on that illegal combination, and a network failure becomes a long-lived interface ghost.

The timing is also narrow. If rollback waits for an animation to finish or a page to leave before rewinding, people have already planned the next glance on the optimistic state. A late rewind collides with that plan. The frame the authority refuses should complete the erase: optimistic pixels gone, pre-failure pixels present. A notice may overlay that frame; it must not use the halfway object as the notice.

Where it stops holding

A failure that needs handling (enter a code, pick another recipient) opens a new, named dialog on top of the pre-failure state; that is not a trace, it is a new task. A trace is a nameless half-state. “Pending send” in an offline queue is a legal state because it is queryable, cancellable, and promises later honouring; a rollback failure is not a queue and should not borrow pending’s look. A few frames of motion from optimistic back to pre-failure are fine if the terminal frame is pre-failure and intermediate frames are not interactive new objects. List virtualisation that, after rollback, leaves row height or scroll position wrong is also a trace — the content is right, the space still sits in a layout that had been optimistic.

Applying it

  • Snapshot each optimistic field at pre-failure; on refusal, replace with the snapshot. Do not merely restyle the optimistic value.
  • The terminal rollback state must not retain “sending”, “syncing”, a translucent row, a frozen bar.
  • Overlay the notice on a clean pre-failure UI (toast, in-row error). Do not let the halfway object speak for itself.
  • How to check: like optimistically, force failure. The terminal frame should be unlit, not a grey heart or a spinner. Post a comment and fail: that row should be absent, scroll as if it had never been inserted. Step the recording; if some frame between optimistic and pre-failure holds more than half a second and is tappable, that is a trace.

Related

  • Same group: I3.09.2 Stacked optimistic steps need a defined rollback radius · I3.09.3 A rollback notice must say why it failed and whether retry is possible · I3.09.4 Don't commit later decisions to an unconfirmed optimistic result
  • Nearby: I3.02 Optimistic updates · I3.01 Visibility of system status
  • Search terms: clean rollback · optimistic restore · pending ghost

Cards in the same group

Quick Actions

Share

Share this page

ios_share

https://hci.top/en/handbook/I3.09.1