* Add state machine activity * address greptile state machine feedback * address state machine trigger cancellation feedback
112 lines
7.5 KiB
Markdown
112 lines
7.5 KiB
Markdown
# 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.
|