Skip to main content

yarli_cli/yarli-core/src/fsm/
task.rs

1//! Task state machine (Section 7.2).
2//!
3//! Rules:
4//! - TASK_COMPLETE requires successful gate evaluation and required evidence.
5//! - TASK_BLOCKED must carry a machine-readable blocker code.
6//! - Retry transitions must increment attempt_no.
7
8use serde::{Deserialize, Serialize};
9
10/// Task lifecycle states.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
13pub enum TaskState {
14    TaskOpen,
15    TaskReady,
16    TaskExecuting,
17    TaskWaiting,
18    TaskBlocked,
19    TaskVerifying,
20    TaskComplete,
21    TaskFailed,
22    TaskCancelled,
23}
24
25impl TaskState {
26    /// Terminal states cannot transition further.
27    pub fn is_terminal(self) -> bool {
28        matches!(
29            self,
30            TaskState::TaskComplete | TaskState::TaskFailed | TaskState::TaskCancelled
31        )
32    }
33
34    /// Returns the set of states reachable from this state.
35    pub fn valid_transitions(self) -> &'static [TaskState] {
36        use TaskState::*;
37        match self {
38            TaskOpen => &[TaskReady, TaskBlocked, TaskCancelled],
39            TaskReady => &[TaskExecuting, TaskBlocked, TaskCancelled],
40            TaskExecuting => &[TaskWaiting, TaskVerifying, TaskFailed, TaskCancelled],
41            TaskWaiting => &[TaskExecuting, TaskBlocked, TaskFailed, TaskCancelled],
42            TaskBlocked => &[TaskReady, TaskFailed, TaskCancelled],
43            TaskVerifying => &[TaskComplete, TaskFailed, TaskBlocked, TaskCancelled],
44            TaskComplete => &[],
45            TaskFailed => &[TaskReady], // retry
46            TaskCancelled => &[],
47        }
48    }
49
50    /// Check if transitioning to `target` is valid.
51    pub fn can_transition_to(self, target: TaskState) -> bool {
52        self.valid_transitions().contains(&target)
53    }
54}