A way of designing software where the conditions it can be in are treated as the work, not as edge cases to handle later. Use it for a feature, a surface, or a single screen—anywhere a system behaves over time.
This method came out of a video on my YouTube channel Interface Studies: The Happy Path Doesn't Exist.
Software behaves. It runs, pauses, fails, sits idle, returns to itself days later, and appears on surfaces the user may never open. A wireframe captures one condition. A flow diagram captures one path. What you ship lives in the conditions around both.
The vocabulary we use puts the work in order: happy path first, edge case later, user journey flattened to a line. An edge case, by its name, is what the ideal displaced. That is why it ends up at the bottom of the backlog.
States are not deviations from the system; they are part of the system. A paused timer is no less real than a running one. The screen shown when someone returns to a half-finished task two days later matters as much as the screen they started with.
Once a condition has a name, evidence, scope, owner, and acceptance criteria, it has a place in the project. Renaming “edge case” is only the opening move. The method keeps the resulting work honest under deadlines.
Four steps:
- Describe. Write one sentence about what the system is as an object that exists over time.
- Map. Build four related inventories: lifecycle states, failures, interruptions, and surfaces. They are four lenses, not four equivalent state-machine node types.
- Decide. Record evidence, risk, and scope for each condition:
in,out-with-implication, orout. A tool can recommend; the team decides. - Specify. Give every in-scope condition an owner, behavior, and acceptance criteria. Add category-specific recovery or surface requirements, then run the five-question re-entry review on every in-scope lifecycle state.
The output is a condition map: systematic coverage of the materially distinct conditions relevant to the current feature and iteration. It is not a proof that an effectively infinite state space has been exhausted, and it is not an executable state machine.
Use it to reorganise a design file, create implementation stories and tests, or maintain a human-readable STATEFUL.md and optional JSON mirror. PRACTICE.md defines the complete working method.
- Lifecycle state: a condition the product or domain can persist in or render distinctly.
- Failure: a rejected or unsuccessful transition requiring a deliberate response.
- Interruption: context that changes how the system must reconcile or render on return.
- Surface: a projection channel with its own content, action, accessibility, freshness, and privacy constraints.
These dimensions compose. “Dose overdue” may be entered after a timezone change, from a watch notification, while another device has unsynced data. Stateful records each dimension and the typed relationships between them without pretending they are interchangeable.
On a whiteboard, a notebook is enough. This works well for greenfield features when the people with product, design, engineering, support, and domain knowledge are present.
With an agent, the skills in skills/ accelerate discovery, evidence gathering, triage, specification, auditing, prompts, and graphing:
# Claude Code
/plugin marketplace add mskayyali/Stateful
/plugin install stateful@stateful
# Codex (then install from /plugins and start a new session)
codex plugin marketplace add mskayyali/Stateful
# Most other agents
npx skills add mskayyali/Stateful
Agents make candidate generation cheap. They do not supply missing domain evidence or own scope decisions. Existing-product audits should include code and tests plus requirements, analytics, incidents, support history, research, and domain expertise where available.
Stateful is a discovery and specification layer. Pair it with the artifacts your team already trusts: statecharts, decision tables, use cases, design components, work items, automated tests, runbooks, and telemetry.
Do not treat the JSON mirror as a direct code-generation target. Typed relationships can be translated into an executable model only after guards, actions, invariants, hierarchy, concurrency, and event semantics have been designed in the target formalism.
The repository includes a dependency-free validator for the condition maps and CI checks for examples, local links, skill frontmatter, JSON syntax, and plugin version alignment. The default profile accepts in-progress working memory; --profile handoff additionally requires every in-scope condition to be specified.
python3 scripts/validate_state_map.py --profile handoff EXAMPLES/*/04-state-map.json
python3 scripts/validate_repo.py
Stateful draws on Alistair Cockburn’s Writing Effective Use Cases (main success scenario plus extensions per step), Scott Hurff’s Designing Products People Love (the UI Stack), and Ian Horrocks’s Constructing the User Interface with Statecharts. It is a complementary discovery practice, not a replacement for those techniques.
Version 0.1. Ready for feature-scale pilots; not yet validated at organisational scale. The worked examples are illustrative maps, not evidence of production outcomes.
Dual-licensed:
- Written content: CC BY-SA 4.0.
- Code (
schema.jsonandscripts/): MIT.