Claude
Skills
Sign in
Back

state-machine-design

Included with Lifetime
$97 forever

Statechart and state machine modeling for lifecycle and behavior specification

Design

What this skill does


# State Machine Design Skill

## When to Use This Skill

Use this skill when:

- **State Machine Design tasks** - Working on statechart and state machine modeling for lifecycle and behavior specification
- **Planning or design** - Need guidance on State Machine Design approaches
- **Best practices** - Want to follow established patterns and standards

## Overview

Design finite state machines and statecharts for modeling entity lifecycles, workflows, and system behavior.

## MANDATORY: Documentation-First Approach

Before designing state machines:

1. **Invoke `docs-management` skill** for state machine patterns
2. **Verify implementation patterns** via MCP servers (context7 for XState, etc.)
3. **Base all guidance on Harel statechart semantics**

## State Machine Concepts

### Core Elements

| Element | Description | Example |
|---------|-------------|---------|
| State | Condition the system can be in | `Draft`, `Submitted`, `Paid` |
| Transition | Change from one state to another | `Draft → Submitted` |
| Event | Trigger for a transition | `Submit`, `Pay`, `Cancel` |
| Guard | Condition that must be true | `[hasItems]`, `[isValid]` |
| Action | Side effect on transition | `sendNotification`, `updateDatabase` |
| Entry Action | Action when entering state | `onEnter: startTimer` |
| Exit Action | Action when leaving state | `onExit: stopTimer` |

### State Types

```csharp
public enum StateType
{
    Initial,       // Starting state (filled circle)
    Normal,        // Regular state
    Final,         // End state (circle with border)
    Composite,     // Contains sub-states
    Parallel,      // Concurrent regions
    History,       // Remember last sub-state
    Choice         // Decision point
}
```

## State Machine Notation

### PlantUML Syntax

```plantuml
@startuml
title Order State Machine

[*] --> Draft : Create

state Draft {
  Draft : entry / initializeOrder
  Draft : exit / validateOrder
}

Draft --> Submitted : Submit [hasItems]
Draft --> Cancelled : Cancel

state Submitted {
  Submitted : entry / reserveInventory
}

Submitted --> Paid : ProcessPayment [paymentValid]
Submitted --> Cancelled : Cancel / releaseInventory
Submitted --> Draft : RequireChanges

state Paid {
  Paid : entry / confirmInventory
}

Paid --> Shipped : Ship
Paid --> Refunded : Refund

state Shipped {
  Shipped : entry / sendTrackingNotification
}

Shipped --> Delivered : Deliver
Shipped --> Returned : Return

Delivered --> Completed : Finalize
Delivered --> Returned : Return

Returned --> Refunded : ProcessReturn

Completed --> [*]
Refunded --> [*]
Cancelled --> [*]

@enduml
```

### Mermaid Syntax

```mermaid
stateDiagram-v2
    [*] --> Draft : Create

    state Draft {
        direction LR
        [*] --> Empty
        Empty --> HasItems : AddItem
        HasItems --> HasItems : AddItem
        HasItems --> Empty : RemoveLastItem
    }

    Draft --> Submitted : Submit
    Draft --> Cancelled : Cancel

    Submitted --> Paid : PaymentReceived
    Submitted --> Cancelled : Cancel
    Submitted --> Draft : RequireChanges

    Paid --> Shipped : Ship
    Paid --> Refunded : Refund

    Shipped --> Delivered : Deliver
    Shipped --> Returned : Return

    Delivered --> Completed : Finalize
    Delivered --> Returned : Return

    Returned --> Refunded : ProcessReturn

    Completed --> [*]
    Refunded --> [*]
    Cancelled --> [*]
```

## C# Implementation Patterns

### Simple State Machine

```csharp
public sealed class Order : Entity
{
    public OrderStatus Status { get; private set; }

    private static readonly Dictionary<(OrderStatus From, OrderEvent Event), OrderStatus> _transitions =
        new()
        {
            { (OrderStatus.Draft, OrderEvent.Submit), OrderStatus.Submitted },
            { (OrderStatus.Draft, OrderEvent.Cancel), OrderStatus.Cancelled },
            { (OrderStatus.Submitted, OrderEvent.Pay), OrderStatus.Paid },
            { (OrderStatus.Submitted, OrderEvent.Cancel), OrderStatus.Cancelled },
            { (OrderStatus.Submitted, OrderEvent.RequireChanges), OrderStatus.Draft },
            { (OrderStatus.Paid, OrderEvent.Ship), OrderStatus.Shipped },
            { (OrderStatus.Paid, OrderEvent.Refund), OrderStatus.Refunded },
            { (OrderStatus.Shipped, OrderEvent.Deliver), OrderStatus.Delivered },
            { (OrderStatus.Shipped, OrderEvent.Return), OrderStatus.Returned },
            { (OrderStatus.Delivered, OrderEvent.Finalize), OrderStatus.Completed },
            { (OrderStatus.Delivered, OrderEvent.Return), OrderStatus.Returned },
            { (OrderStatus.Returned, OrderEvent.ProcessReturn), OrderStatus.Refunded },
        };

    public Result Transition(OrderEvent @event)
    {
        if (!_transitions.TryGetValue((Status, @event), out var newStatus))
        {
            return Result.Failure($"Cannot {@event} order in {Status} status");
        }

        var oldStatus = Status;
        Status = newStatus;

        AddDomainEvent(new OrderStatusChangedEvent(Id, oldStatus, newStatus, @event));

        return Result.Success();
    }
}

public enum OrderStatus
{
    Draft, Submitted, Paid, Shipped, Delivered, Completed, Cancelled, Returned, Refunded
}

public enum OrderEvent
{
    Submit, Cancel, Pay, RequireChanges, Ship, Refund, Deliver, Return, Finalize, ProcessReturn
}
```

### State Pattern Implementation

```csharp
public abstract class OrderState
{
    public abstract OrderStatus Status { get; }

    public virtual Result Submit(Order order) =>
        Result.Failure($"Cannot submit order in {Status} state");

    public virtual Result Cancel(Order order) =>
        Result.Failure($"Cannot cancel order in {Status} state");

    public virtual Result Pay(Order order) =>
        Result.Failure($"Cannot pay order in {Status} state");

    public virtual Result Ship(Order order) =>
        Result.Failure($"Cannot ship order in {Status} state");

    protected void TransitionTo(Order order, OrderState newState)
    {
        order.SetState(newState);
    }
}

public sealed class DraftState : OrderState
{
    public override OrderStatus Status => OrderStatus.Draft;

    public override Result Submit(Order order)
    {
        if (!order.HasItems)
            return Result.Failure("Order must have items to submit");

        TransitionTo(order, new SubmittedState());
        order.ReserveInventory();
        return Result.Success();
    }

    public override Result Cancel(Order order)
    {
        TransitionTo(order, new CancelledState());
        return Result.Success();
    }
}

public sealed class SubmittedState : OrderState
{
    public override OrderStatus Status => OrderStatus.Submitted;

    public override Result Pay(Order order)
    {
        TransitionTo(order, new PaidState());
        order.ConfirmInventory();
        return Result.Success();
    }

    public override Result Cancel(Order order)
    {
        order.ReleaseInventory();
        TransitionTo(order, new CancelledState());
        return Result.Success();
    }
}
```

### Stateless Library Pattern

```csharp
using Stateless;

public sealed class OrderStateMachine
{
    private readonly StateMachine<OrderStatus, OrderEvent> _machine;
    private readonly Order _order;

    public OrderStateMachine(Order order)
    {
        _order = order;
        _machine = new StateMachine<OrderStatus, OrderEvent>(
            () => order.Status,
            status => order.SetStatus(status));

        ConfigureTransitions();
    }

    private void ConfigureTransitions()
    {
        _machine.Configure(OrderStatus.Draft)
            .Permit(OrderEvent.Submit, OrderStatus.Submitted)
            .Permit(OrderEvent.Cancel, OrderStatus.Cancelled)
            .OnEntry(() => _order.InitializeOrder());

        _machine.Configure(OrderStatus.Submitted)
            .PermitIf(OrderEvent.Pay, OrderStatus.Paid,
                () => _order.PaymentIsValid)
            .Permit(OrderEvent.Cancel, OrderStatus.Cancelled)
            .Permit(OrderEvent.Requir

Related in Design