| name | state-list |
| description | List the states of a software system across four categories (active, failure, interruption, surface) using interrogation patterns derived from a structural system sentence. Use this whenever a user has a system sentence (or has just produced one) and needs a structured state list before triage or design work; whenever someone is moving from happy-path thinking to state-first thinking and needs an exhaustive-enough catalogue across the four categories; or as the second step in the Stateful method after the system sentence. Do not use before a system sentence exists, as listing without an anchor drifts into exhaustive taxonomy. For existing products, prefer the state-audit skill, which handles the listing as part of a comparative procedure rather than producing a list disconnected from what already exists. |
State List
Produces a four-category state list (active, failure, interruption, surface) for a system, starting from its system sentence.
Output discipline
No preamble, no narration of the procedure, no restating the method or the sentence. Deliver the output format below plus only what needs the user's decision. Terse but complete: every state keeps its one-line justification; no state gets a paragraph; the coverage section is counts and flags, not commentary.
Procedure
Before starting. Read STATEFUL.md from the working directory if it exists. Use the ## System sentence from it as input, plus any ## Surface(s) in scope for context. If the sentence section carries raw-material bullets (time, lifecycle, channels, completion differences, surfaces), use them as seeds for the corresponding elicitation questions in steps 2 to 5. If no sentence is present, ask the user for one (or run the system-sentence skill first). The sentence must be one the user has confirmed; if it arrived from a system-sentence run without an explicit confirmation, present it with one line on why it works and get the confirmation before listing. If the product has a cross-cutting inventory of recurring conditions (unauthenticated, offline, subscription expired, sync conflict, etc.), reference it while listing this feature's states rather than re-listing cross-cutting conditions from scratch; note in the output which listed states inherit from the cross-cutting inventory.
-
Read the system sentence. Extract its structural terms (verbs and time-bearing nouns) into an explicit list. If the system-sentence skill already produced a Structural terms: list, use it verbatim. This list is the coverage anchor for the whole list: every term must generate at least one active state, and step 7 checks this before stopping.
-
List active states first, derived directly from the sentence's verbs. Expect 8–15 for a non-trivial system.
-
For each active state, ask: what could prevent the next transition? Record the answers as failure states. Record an explicit none where the question genuinely yields nothing; silence and none are different results, and the coverage check in step 7 needs to tell them apart.
-
For each active state, ask: what happens if the user leaves, time passes, or the context changes? Record the answers as interruption states. Same rule: explicit none where nothing yields.
-
List the surfaces the system renders on: web, mobile web, native iOS, native Android, email, push, screen reader, watch, print. Each is a surface state. Populate renders_on on each non-surface state as you go.
-
Review the list for duplicates and specialisations. A state that is a narrower version of another state should be merged or annotated, not listed separately.
-
Run the coverage check, then apply the stopping rule. The coverage check has four rows:
- Term coverage. Every structural term from step 1 has generated at least one active state. A term that generated nothing is either decorative (flag it; the sentence may need a rewrite) or hiding states not yet found (interrogate it directly before proceeding).
- Interrogation coverage. Every active state has an explicit answer, or an explicit none, recorded for the failure question (step 3) and the interruption question (step 4). Any state with a blank gets asked now.
- Surface coverage. Every surface from step 5 maps to at least one surface state, and every active state has
renders_on populated, is marked transient, or is noted as backend-only or rendered outside the product. Failure and interruption states inherit surfaces from the active states they attach to; annotate them only where the surface differs.
- Cross-cutting coverage. If a cross-cutting inventory exists, every applicable inherited condition is either present in this list or explicitly noted as not applying to this feature.
Only after the coverage check passes: stop when three successive attempts to add a state produce only specialisations of states already on the list, rather than new ones. Do not continue past this point.
-
(Optional) For each state, annotate which layers it engages: frontend, backend, data-model, infrastructure. The distinguishing question: which layer would have to change to implement this state? Skip this step for greenfield design before the system has been split into layers; include it for any cross-functional project where the layer split matters.
8a. (Optional, failure states) For each failure state, annotate its cause: user-input (rejection due to what the user provided), system (internal error or bug), external (external dependency failed), policy (deliberate business rule rejection). The distinguishing question: what is the source of the rejection? This is independent of rendering; it captures why the failure happened, which informs the design of the response surface. Optional on interruption states where the distinction is useful.
-
Ask the user whether they want a machine-readable mirror. If STATEFUL.md already records a decision on this in its ## Decisions section (e.g., state-map.json: yes or state-map.json: no), respect it without re-asking. Otherwise ask:
Would you also like a state-map.json mirror produced? This is an optional JSON file validating against schema.json. It is useful if you want machine validation, a contract for downstream tooling, or a codegen target (e.g. XState). The methodology does not require it; STATEFUL.md plus the design file are the handoff artefacts. Reply yes or no.
If yes, produce a state-map.json in the working directory containing the list so far (states with id, name, category, optional layers; transitions and reentry_variants will be added by later skills). Record state-map.json: yes in the ## Decisions section of STATEFUL.md. If no, record state-map.json: no instead.
-
Return the four-category list with a short annotation on each state explaining why it is included; include layers if step 8 was run, and a one-line note on whether the JSON mirror was produced.
Working memory. Update STATEFUL.md in the working directory: replace the contents of the ## State list section with the per-category counts (active, failure, interruption, surface) and a pointer to the machine-readable map (e.g., state-map.json if it exists). If the file does not exist, create it. Stamp Last updated: <date> by state-list. If STATEFUL.md contains a ## Graph section, regenerate it from the updated map following the state-graph skill's conventions, preserving the cut recorded in ## Decisions.
For richer elicitation patterns beyond steps 2–5 (incident archaeology, multi-actor reads, the "and then what?" drill), see the Finding states section in PRACTICE.md. Run additional patterns when the basic four steps yield a thin list.
Inputs required
- The system sentence.
- Optional: the product's existing surfaces (web, iOS, Android, etc.). If not provided, ask once.
Output format
## Active states
1. <state>. <one-sentence justification>
2. ...
## Failure states
N. <state>. <one-sentence justification>
...
## Interruption states
...
## Surface states
...
## Coverage
- Term coverage: <n>/<n> structural terms generated states. <flagged terms, if any>
- Interrogation coverage: <n>/<n> active states have failure and interruption answers (or explicit none).
- Surface coverage: <n>/<n> surfaces mapped; renders_on populated on all non-surface states.
- Cross-cutting: <inherited count, or "no inventory">
Total: <count>. Stopped because <reason, typically: further items became specialisations>.
Common failure modes
- Pursuing completeness. The list chases every possible state and the listing stalls. Stop at exhaustive-enough.
- Stopping on the count, not the coverage. A list of 40 states can still have a structural term that generated nothing and three active states nobody asked the failure question about. The stopping rule measures saturation; the coverage check measures whether the interrogation actually happened. Both must pass.
- Naming states for screens. "The settings screen" is not a state. "Configuration unsaved" is. Rename.
- Conflating failure and interruption. Apply the pragmatic rule from PRACTICE: failure if the design work is a rendered rejection at the moment of action; interruption if the design work is a re-entry specification on return. A network drop during submission is a failure (the user sees an error at submit). A tab closed mid-flow is an interruption (the user encounters the consequence on return).
- Omitting surfaces on the assumption it is handled elsewhere. Surfaces are a category of state, not a post-hoc layer.
- Listing without commentary. A bare list is not useful for triage. Each state deserves one sentence of justification.
Example
Input: System sentence for password reset: "A password reset is a time-bound, single-use credential-replacement process, initiated from one context, continued via an out-of-band message, and completed under conditions that may differ from those at initiation."
Partial output (active category only, truncated for brevity):
## Active states
1. Request form, empty. The initial state of the request surface.
2. Request form, email entered. Email is present; submit not pressed.
3. Request submitted, awaiting delivery. Backend has accepted; email is being composed.
4. Request acknowledged, email sent. Origin surface renders confirmation.
5. Link clicked, token being validated. Transient check of validity and single-use.
6. New-password form, empty. Token valid; form presented.
...
See EXAMPLES/password-reset/01-state-list.md for the complete worked example.