# States

> Design the $machine section — map happy paths, error paths, and all state types into a complete behavioral skeleton

- Skill: `johnlindquist/states` (Agent Skill)
- Install (CLI): `npx skillmds@latest add johnlindquist/states`
- Raw SKILL.md: https://api.skillmd.com/api/skills/johnlindquist/states/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: johnlindquist (https://skillmd.com/u/johnlindquist)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/johnlindquist/states

---


# States: State Machine Design

Design the `$machine` — the behavioral skeleton of a UXSpec. Every state is a promise to the user about what they can do and what they'll see.

## When to Use

When building or revising the `$machine` section. Also useful for auditing an existing spec's state coverage.

## Process

### 1. Map the Happy Path
Start with the ideal flow: entry → action → outcome. Define compound states (parents) and leaf states (children). Every compound state needs an `initial` child.

```
idle --SUBMIT--> loading
loading --HTTP_OK--> success
```

### 2. Map the Unhappy Paths
For every transition, ask: what else could happen?
- **Network failure** — timeout, server error, no connection
- **Validation failure** — bad input, missing fields, format errors
- **Permission failure** — expired session, insufficient role, rate limited
- **Concurrent conflict** — double submission, stale data, race condition

Each failure needs a state (or at least a handled transition) — not just an afterthought.

### 3. Cover All State Types
A complete machine accounts for:
- **Empty** — no data yet, no results, first-time use. These are onboarding opportunities.
- **Loading** — initial fetch, pagination, background refresh. Each may need different visuals.
- **Error** — network, validation, permissions, rate limiting. Each needs different copy and recovery.
- **Success** — confirmation, next steps, celebration. What happens after the goal is met?
- **Partial** — some data loaded, some fields valid. Don't force all-or-nothing.

### 4. Simplify
For each state, ask: is this truly necessary?
- Can two states merge? (e.g., "loading" and "refreshing" might be one state with a context flag)
- Is a state reachable? (orphaned states are dead weight)
- Does every state have a way out? (no dead ends)
- Look for the 20% of states delivering 80% of value.

### 5. Wire Transitions
- Map events to transitions with optional guards and actions
- Add `entry`/`exit` actions (set loading flags, clear errors, reset forms)
- Add `invoke` for long-running effects (HTTP calls, timers, polling)
- Use `always` transitions with guards for automatic routing (e.g., redirect if already authenticated)

## Diagram

Present the state graph as text before writing JSON:

```
idle --SUBMIT--> loading
loading --HTTP_OK--> success
loading --HTTP_ERROR--> error
error --RETRY--> loading
success --RESET--> idle
```

## Principle

A state machine is a contract: "in this state, these things are true and these things are possible." If a state doesn't change what the user sees or can do, it doesn't belong.

