Skip to main content

ralph/execution_history/
model.rs

1//! Execution-history data models.
2//!
3//! Responsibilities:
4//! - Define persisted execution-history structs.
5//! - Provide schema-version defaulting for new histories.
6//!
7//! Not handled here:
8//! - Disk IO.
9//! - Weighted-average calculations.
10//!
11//! Invariants/assumptions:
12//! - `ExecutionHistory::default()` always uses the current schema version.
13//! - Entries remain serializable for cache persistence.
14
15use crate::constants::versions::EXECUTION_HISTORY_VERSION;
16use crate::progress::ExecutionPhase;
17use serde::{Deserialize, Serialize};
18use std::collections::HashMap;
19use std::time::Duration;
20
21/// Root execution history data structure.
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct ExecutionHistory {
24    /// Schema version for migrations.
25    pub version: u32,
26    /// Historical execution entries.
27    pub entries: Vec<ExecutionEntry>,
28}
29
30impl Default for ExecutionHistory {
31    fn default() -> Self {
32        Self {
33            version: EXECUTION_HISTORY_VERSION,
34            entries: Vec::new(),
35        }
36    }
37}
38
39/// A single execution entry recording phase durations.
40#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct ExecutionEntry {
42    /// When the execution completed (RFC3339).
43    pub timestamp: String,
44    /// Task ID that was executed.
45    pub task_id: String,
46    /// Runner used (e.g., "codex", "claude").
47    pub runner: String,
48    /// Model used (e.g., "sonnet", "gpt-4").
49    pub model: String,
50    /// Number of phases configured (1, 2, or 3).
51    pub phase_count: u8,
52    /// Duration for each completed phase.
53    pub phase_durations: HashMap<ExecutionPhase, Duration>,
54    /// Total execution duration.
55    pub total_duration: Duration,
56}