I3.13.4UI as state-machine projectiondesign

The UI must be a projection of the state machine, not a visual guess

Aliases: view is not state · visual guess · one source

What it is

Every on-screen “how it is now” — button copy, a spinner, red error type, disabled — must be a projection of that one underlying node, not a visual state living on its own. People (and tests, and assistive tech) must not guess which cell the machine is in from “it looks like it is loading”. If it looks like one cell and the machine is in another, the next event walks the other cell’s edge, and both picture and causation lie.

Correspondence is two-way: every legal node has a distinguishable presentation; every presentation points back to one node. Many-to-one (several nodes that look the same) makes evaluation impossible; one-to-many (the same node sometimes spins and sometimes does not) makes people think a transition happened.

Why it happens

Vision is fast, local, easily rewritten by animation and style branches. The state machine is a beat slower, gated on events. If each keeps its own copy, vision moves first: a designer adds a “shimmer before load completes”, engineering never gave it a node, and the shimmer becomes a false state with no edge. Or the reverse: the machine is already at failure, vision still sits on last time’s success green because that green was leftover style. People decide from green; events walk failure’s edge.

Strict correspondence is a single source: the interface is drawn from a function of the node, not from “the class last left behind”. Tests ask the node; snapshots ask whether the projection is one-to-one. The name assistive tech reads should be the node’s name, not “button 1”. Visual guess is tempting because acceptance uses the eye in place of reading state — the eye passed, the machine did not.

Where it stops holding

Decorative motion (a press scale on a button) is not a node and need not enter the machine; it must overlay the node’s projection, and cannot by itself be evidence of “how it is now”. Several windows, several objects, each with a machine: correspondence is each machine to its patch of UI, not one node for the whole screen. An optimistic layer is an explicit extra node (“locally committed, unconfirmed”), not another painting of the same node; painting it indistinguishable from “confirmed” is correspondence failure. Skin, theme, density change pixels and should not change distinguishability: failure in a dark theme must still be failure, not look like disabled.

Applying it

  • Write a presentation spec per node: which controls, which copy, disabled or not, accessible name. A frame outside the spec is a bug.
  • UI code reads only the current node, not “last time’s style” or a parallel isXxx.
  • Accept by reading the current node, not by looking at colour: automation asserts the enum, not whether a screenshot looks like a spinner.
  • How to check: park the machine on failure, ask someone who has not seen the code “what state is this”. If they say “still loading” or “looks like it succeeded”, the projection did not correspond. Then cut the node across the five legal values; each cut should jump to the spec’d frame, and the name assistive tech reports should follow. Deliberately leave a success green and then cut to failure: if the green remains, the guess was from visual residue.

Related

  • Same group: I3.13.1 Every legal transition must have a defined outcome · I3.13.2 If the data model can hold an illegal combination, it will · I3.13.3 Independent booleans mint illegal states that a single enum would forbid
  • Nearby: I3.01 Visibility of system status · I3.02 Optimistic updates
  • Search terms: view-state correspondence · single source of truth · projection

Cards in the same group

Quick Actions

Share

Share this page

ios_share

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