elsa-core/specs/006-state-machine-activity/spec.md
Sipke Schoorstra 6485f05a87
Add state machine activity (#7457)
* Add state machine activity

* address greptile state machine feedback

* address state machine trigger cancellation feedback
2026-05-18 02:09:03 +02:00

7.5 KiB

Feature Specification: State Machine Activity

Feature Branch: 006-state-machine-activity
Created: 2026-05-16
Status: Draft
Input: GitHub issue #5085, "State Machine Activity"

Clarifications

Session 2026-05-16

  • Q: What should a state machine do after it enters a state that has no valid outbound transitions? → A: Complete the StateMachine when the current state has no valid outbound transitions.
  • Q: What should happen to the transition trigger whose condition evaluates false? → A: Keep the failed transition trigger active so it can fire again later.

User Scenarios & Testing (mandatory)

User Story 1 - Run a State Through Entry and Triggers (Priority: P1)

A workflow author can model a state machine with an initial state, entry action, exit action, and outbound transitions whose trigger activities wait for external or delayed stimuli.

Why this priority: This is the minimum useful server-side state machine behavior and proves that Elsa can keep a workflow instance active while a state waits for transition triggers.

Independent Test: Execute a state machine with two states and one transition, then verify that initial state entry and outbound trigger scheduling happen without completing the state machine.

Acceptance Scenarios:

  1. Given a state machine with an initial state and entry action, When the state machine executes, Then the entry action is scheduled before outbound transition triggers.
  2. Given a current state with outbound transitions, When entry completes, Then each outbound transition trigger is scheduled and the state machine remains running.

User Story 2 - Complete a Winning Transition (Priority: P2)

A transition trigger can win, evaluate its condition, run its action, exit the source state, enter the target state, and update the current state.

Why this priority: This completes the central state transition behavior from the issue.

Independent Test: Simulate trigger and action completion for a transition whose condition is true, then verify current state, action, source exit, target entry, and target triggers.

Acceptance Scenarios:

  1. Given a transition whose trigger completed and condition is true, When the transition is accepted, Then its action is scheduled.
  2. Given an accepted transition action completes, When source exit and target entry complete, Then the current state is the target state and target outbound triggers are scheduled.
  3. Given a transition has no condition, When its trigger completes, Then the transition is treated as eligible.

User Story 3 - Cancel Competing Triggers (Priority: P3)

When one outbound transition wins, competing outbound transition triggers from the same source state are canceled so the state machine cannot take multiple outbound paths.

Why this priority: This preserves deterministic state-machine semantics with multiple pending triggers.

Independent Test: Execute a state with two outbound transitions, complete one trigger, and verify the other trigger context is canceled.

Acceptance Scenarios:

  1. Given multiple outbound transition triggers are pending, When one trigger wins, Then all other outbound transition trigger contexts from that source state are canceled.
  2. Given a transition condition evaluates false, When its trigger completes, Then no transition action is scheduled, competing triggers remain pending, and the failed transition trigger remains active for a future attempt.

Edge Cases

  • A missing initial state completes the state machine without scheduling children.
  • A missing source or target state on a transition prevents that transition from being scheduled.
  • A missing trigger means that transition cannot be scheduled.
  • A missing entry, exit, or action slot is treated as an empty step that immediately advances the state machine.
  • A state with no valid outbound transitions is terminal and completes the state machine after its entry action completes.
  • A trigger whose transition condition evaluates false is re-armed so the same transition can be attempted again later.
  • Duplicate state names are resolved by the first state in declaration order.

Requirements (mandatory)

Functional Requirements

  • FR-001: System MUST provide a StateMachine activity with States, Transitions, InitialState, and observable CurrentState values.
  • FR-002: System MUST provide a State model with Name, optional Entry, and optional Exit activity slots.
  • FR-003: System MUST provide a Transition model with Name, DisplayName, From, To, optional Trigger, optional Condition, and optional Action.
  • FR-004: State machine execution MUST start from CurrentState when set, otherwise InitialState.
  • FR-005: Entering a state MUST schedule its entry action before outbound transition triggers.
  • FR-006: After state entry completes, the state machine MUST schedule all valid outbound transition triggers for the current state.
  • FR-007: A completed trigger MUST evaluate its transition condition; missing conditions MUST be treated as true.
  • FR-008: An eligible transition MUST run its action before leaving the source state.
  • FR-009: A completed transition action MUST schedule the source state's exit action and then the target state's entry action.
  • FR-010: A completed transition MUST update CurrentState to the target state before scheduling the target state's outbound triggers.
  • FR-011: When one transition is accepted, all other pending outbound transition triggers for the same source state MUST be canceled.
  • FR-012: A false transition condition MUST leave the state machine in the same state, MUST NOT cancel competing triggers, and MUST keep the failed transition trigger active for a future attempt.
  • FR-013: A state with no valid outbound transitions MUST complete the state machine after any entry action completes.
  • FR-014: Unit tests MUST cover initial execution, true and false transition conditions, empty slots, terminal states, and competing trigger cancellation.

Key Entities (include if feature involves data)

  • StateMachine: Activity that owns state declarations, transition declarations, and current state progress.
  • State: Named state with optional entry and exit activities.
  • Transition: Directed path from one state to another with trigger, condition, and action slots.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: A two-state workflow can wait in its initial state with at least one pending transition trigger.
  • SC-002: A trigger with a true condition moves the machine to its target state and schedules the next state's triggers.
  • SC-003: A trigger with a false condition leaves the state unchanged and keeps other outbound trigger work active.
  • SC-004: A transition into a state with no valid outbound transitions completes the state machine.
  • SC-005: Unit tests for the activity pass without external services.

Assumptions

  • This change covers server-side workflow execution in elsa-core; the dedicated Studio designer from issue #5085 remains separate work.
  • States and transitions are stored as activity properties using existing Elsa serialization patterns.
  • Transition source and target references use state names for the first server-side implementation.
  • Trigger bookmark cleanup relies on canceling the losing trigger activity execution contexts through existing Elsa cancellation behavior.