The system cannot assume users follow a preset flow
Aliases: predetermined process · process rigidity · exception design · dirty data
What it is
A predetermined wizard, a linear state machine, and a strictly ordered form each describe only one possible path. Real users interrupt, skip, repeat, work in parallel, reorder, or hand off to someone else. If a system treats the predetermined process as a necessary condition, it locks the task up or produces dirty data whenever an exception occurs. This card is where the previous two cards' logic lands in engineering practice: if a plan is only a resource and real action depends on situated adjustment, then hard-coding the predetermined process as the only path the system allows is using an engineering implementation to deny a reality the theory has already established — and the conflict will eventually surface in real use.
Why it happens
A predetermined process drifts from reality because it is usually derived from the angle of "how this should ideally be done," and that derivation naturally leaves out several genuinely occurring situations: several roles needing to handle the same thing in parallel, a step that must wait for external information before it can proceed, what state the system should return to after an operation is undone, how a task should hand off when someone else takes over midway. When real user behavior lands exactly in one of these unconsidered cases — entering midway through the process, submitting missing material later, having a colleague fill in part of it — the system usually has no corresponding state, permission, or validation logic at all. The user either gets stuck with no way forward, or is forced to work around the system entirely, finish the thing some other way, and then jam the result back into the system afterward in a way that looks compliant. That latter case is exactly where dirty data comes from: the data itself is not false, but it does not record the order things actually happened in — it records a version reverse-engineered to look compliant with the system's process. The cost of this rigidity is not that exceptions disappear; it is that the real work of handling exceptions gets pushed outside the system, off the record, leaving a crack between what the system shows and what actually happened that the system itself cannot see at all.
Where it stops holding
Not assuming linearity does not mean allowing any order at all and abandoning every constraint. Safety-related operation sequences, legally required signing steps, and data relationships with a genuine ordering dependency still need hard constraints enforced, and there is nothing wrong with the constraints themselves — the real problem is how that constraint is presented to the user. A hard constraint should explicitly state why it exists, what condition would lift it, and what alternative path exists if that condition cannot currently be met, rather than simply showing a disabled button and leaving the user to guess whether it is a permission issue, an unmet precondition, or a design flaw in the step itself. Some processes genuinely must be completed in a fixed order by specific roles, and in that case the system needs to distinguish "this step is not yet allowed because a precondition has not been met" from "this operation itself is an error" — two entirely different kinds of state that should not be conflated and shown to the user through the same error message.
Applying it
- Build a richer state model for core processes, covering not just "in progress" and "complete" but precondition, optional, parallel, waiting, cancelled, repeated, and handed-off states that genuinely occur in practice.
- Allow saving partial progress, continuing later, and having someone else take over the unfinished part, while keeping a clear record of ownership and a timeline through every handoff.
- Beside every hard constraint, state the specific reason it exists, what condition would lift it, and whether an alternative path is available if that condition cannot currently be met — do not present just a disabled button.
- How to check: write test scripts from real interruptions and exceptions that have actually occurred and walk through the process specifically looking for a workflow deadlock — a step where the user can neither proceed nor go back — and a missing state, where the situation the user is actually in has no corresponding option in the system at all.