state-machine-design
Designs finite state machines as pure, declarative transition tables with guards and actions. Use when modeling lifecycle states, status flows, or any system with discrete states and controlled transitions.
Best use case
state-machine-design is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Designs finite state machines as pure, declarative transition tables with guards and actions. Use when modeling lifecycle states, status flows, or any system with discrete states and controlled transitions.
Teams using state-machine-design should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/state-machine-design/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How state-machine-design Compares
| Feature / Agent | state-machine-design | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Designs finite state machines as pure, declarative transition tables with guards and actions. Use when modeling lifecycle states, status flows, or any system with discrete states and controlled transitions.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# State Machine Design Patterns
## Rule Anchor
- `AGENTS.md` > "Development Patterns"
- `AGENTS.md` > "Execution Safety"
## Use This Skill When
- An entity has a lifecycle with discrete statuses (e.g., queued, running, success, failed).
- You need to prevent invalid state transitions at compile or runtime.
- Business logic depends on "current state + event → next state" decisions.
- You want transition logic to be testable as pure functions.
## Core Principles
1. **Declarative transition table**: all valid transitions are listed explicitly.
2. **Guard conditions**: boolean predicates that must be true for a transition to fire.
3. **Actions**: side-effect-free data transformations triggered on transition.
4. **Rejection by default**: any transition not in the table is an error.
5. **Purity**: the state machine itself has no I/O; callers perform side effects.
## Workflow
1. List all possible states as a union type or enum.
2. List all possible events (triggers).
3. Build a transition table: `(currentState, event) → nextState | error`.
4. Add guard conditions where transitions require extra checks.
5. Implement as a pure function: `transition(current, event, context?) → Result<nextState, TransitionError>`.
6. Callers invoke the function, then persist state and emit events.
7. Test exhaustively with table-driven test cases.
## Reference Skeleton
```ts
// 1. States and events as union types
type TTaskRunStatus = 'queued' | 'running' | 'success' | 'failed' | 'upstream_failed' | 'skipped';
type TTaskRunEvent = 'DISPATCH' | 'LEASE_ACQUIRED' | 'COMPLETE' | 'FAIL' | 'SKIP' | 'UPSTREAM_FAIL';
// 2. Transition error
type TTransitionError = { from: TTaskRunStatus; event: TTaskRunEvent; reason: string };
// 3. Transition table (declarative)
const TASK_TRANSITIONS: Record<string, TTaskRunStatus | undefined> = {
'queued:DISPATCH': 'running',
'running:COMPLETE': 'success',
'running:FAIL': 'failed',
'queued:UPSTREAM_FAIL': 'upstream_failed',
'queued:SKIP': 'skipped',
};
// 4. Pure transition function
function transitionTaskRun(
current: TTaskRunStatus,
event: TTaskRunEvent
): { ok: true; status: TTaskRunStatus } | { ok: false; error: TTransitionError } {
const key = `${current}:${event}`;
const next = TASK_TRANSITIONS[key];
if (!next) return { ok: false, error: { from: current, event, reason: 'transition not allowed' } };
return { ok: true, status: next };
}
```
If a reprocess path is required, model it behind an explicit policy gate in a separate layer instead of making `failed -> queued` part of the default machine.
## Checklist
- [ ] All states are listed as a finite union type.
- [ ] All events are listed as a finite union type.
- [ ] Transition table covers every valid (state, event) pair.
- [ ] Unlisted transitions return a typed error (no silent ignoring).
- [ ] Transition function is pure (no I/O, no logger, no storage).
- [ ] Guards are separate pure predicates when needed.
- [ ] Side effects (persist, emit event) happen in the caller, not the machine.
- [ ] Table-driven tests cover all valid transitions and at least one invalid per state.
## Anti-Patterns
- State machine that writes to DB or emits events internally.
- Using `if/else` chains instead of a declarative transition table.
- Silently ignoring invalid transitions instead of returning an error.
- States represented as magic strings instead of typed unions.
- Mixing transition logic with orchestration logic in the same function.Related Skills
web-design-guidelines
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
vitest-testing-strategy
Defines a practical testing strategy for TypeScript and JavaScript using Vitest across unit, integration, and type-level tests. Use when adding features, refactoring, or preventing regressions with fast feedback loops.
version-management
All packages must have the same version. Use changesets for coordinated version bumps. Never version packages independently.
vercel-react-native-skills
React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.
vercel-react-best-practices
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
vercel-composition-patterns
React composition patterns that scale. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or designing reusable APIs. Triggers on tasks involving compound components, render props, context providers, or component architecture. Includes React 19 API changes.
user-request-gate
Use immediately when the user requests any implementation, code change, feature addition, fix, or modification. Gates code writing behind a backlog draft document. Read-only exploration is always permitted.
type-boundary-and-ssot
Applies Robota's preferred workflow for trust-boundary validation, strict typing, quality gates, and owner-based SSOT reuse. Use when adding or reviewing type contracts, boundary parsing, shared contract ownership, or running quality checks.
tdd-red-green-refactor
Kent Beck's TDD workflow. Use when writing new code or modifying existing behavior. Enforces the Red-Green-Refactor cycle with small, verifiable steps.
task-tracking
Track work using task files in .agents/tasks/. Use when starting, progressing, or completing a task to maintain a persistent record of work.
tailwind-truncation
Provide Tailwind truncation patterns for single-line and multi-line text. Use when discussing text ellipsis, truncation, or line-clamp usage.
spec-writing-standard
Use when creating a new SPEC.md or incrementally updating an existing one. Covers both initial authoring and the ongoing incremental-update workflow that keeps the spec live.