1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//! Execution phases and small progress-related contracts.
//!
//! Responsibilities:
//! - Define `ExecutionPhase`, a stable enum used across run history and ETA estimation.
//! - Provide small, display-oriented helpers (phase name/number/icon) without owning rendering.
//!
//! Not handled here:
//! - Rendering progress bars/spinners (CLI or GUI).
//! - Persisting execution history (see `crate::execution_history`).
//! - ETA heuristics (see `crate::eta_calculator`).
//!
//! Invariants/assumptions:
//! - Phase numbering is stable: planning=1, implementation=2, review=3, complete=0.
//! - Serialization format is snake_case for stable on-disk contracts.
use serde::{Deserialize, Serialize};
/// Execution phases for multi-phase task workflows.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ExecutionPhase {
/// Phase 1: Planning and analysis.
Planning,
/// Phase 2: Implementation and CI.
Implementation,
/// Phase 3: Review and completion.
Review,
/// Execution completed.
Complete,
}
impl ExecutionPhase {
/// Returns the human-readable name for this phase.
pub fn as_str(&self) -> &'static str {
match self {
ExecutionPhase::Planning => "Planning",
ExecutionPhase::Implementation => "Implementation",
ExecutionPhase::Review => "Review",
ExecutionPhase::Complete => "Complete",
}
}
/// Returns the phase number (1-3) or 0 for Complete.
pub fn phase_number(&self) -> u8 {
match self {
ExecutionPhase::Planning => 1,
ExecutionPhase::Implementation => 2,
ExecutionPhase::Review => 3,
ExecutionPhase::Complete => 0,
}
}
/// Returns an icon representation of the phase.
///
/// This is used for terminal output; GUIs should render their own icons.
pub fn icon(&self) -> &'static str {
match self {
ExecutionPhase::Planning => "▶",
ExecutionPhase::Implementation => "⚙",
ExecutionPhase::Review => "👁",
ExecutionPhase::Complete => "✓",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn execution_phase_as_str() {
assert_eq!(ExecutionPhase::Planning.as_str(), "Planning");
assert_eq!(ExecutionPhase::Implementation.as_str(), "Implementation");
assert_eq!(ExecutionPhase::Review.as_str(), "Review");
assert_eq!(ExecutionPhase::Complete.as_str(), "Complete");
}
#[test]
fn execution_phase_number() {
assert_eq!(ExecutionPhase::Planning.phase_number(), 1);
assert_eq!(ExecutionPhase::Implementation.phase_number(), 2);
assert_eq!(ExecutionPhase::Review.phase_number(), 3);
assert_eq!(ExecutionPhase::Complete.phase_number(), 0);
}
}