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}