1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use uuid::Uuid;
6
7pub type RunId = Uuid;
9
10pub type TaskId = Uuid;
12
13pub type EventId = Uuid;
15
16pub type CorrelationId = Uuid;
18
19pub type WorktreeId = Uuid;
21
22pub type MergeIntentId = Uuid;
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
27#[serde(rename_all = "snake_case")]
28pub enum EntityType {
29 Run,
30 Task,
31 Worktree,
32 Merge,
33 Command,
34 Gate,
35 Policy,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct Event {
41 pub event_id: EventId,
42 pub occurred_at: DateTime<Utc>,
43 pub entity_type: EntityType,
44 pub entity_id: String,
45 pub event_type: String,
46 pub payload: serde_json::Value,
47 pub correlation_id: CorrelationId,
48 pub causation_id: Option<EventId>,
49 pub actor: String,
50 pub idempotency_key: Option<String>,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct Evidence {
56 pub evidence_id: Uuid,
57 pub task_id: TaskId,
58 pub run_id: RunId,
59 pub evidence_type: String,
60 pub payload: serde_json::Value,
61 pub created_at: DateTime<Utc>,
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct PolicyDecision {
67 pub decision_id: Uuid,
68 pub run_id: RunId,
69 pub actor: String,
70 pub action: String,
71 pub outcome: PolicyOutcome,
72 pub rule_id: String,
73 pub reason: String,
74 pub decided_at: DateTime<Utc>,
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
79#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
80pub enum PolicyOutcome {
81 Allow,
82 Deny,
83 RequireApproval,
84}
85
86#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
88#[serde(rename_all = "snake_case")]
89pub enum ExitReason {
90 CompletedAllGates,
91 BlockedOpenTasks,
92 BlockedGateFailure,
93 MergeConflict,
94 FailedPolicyDenial,
95 FailedRuntimeError,
96 CancelledByOperator,
97 DrainedByOperator,
98 TimedOut,
99 StalledNoProgress,
100}
101
102impl std::fmt::Display for ExitReason {
103 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104 match self {
105 Self::CompletedAllGates => write!(f, "completed_all_gates"),
106 Self::BlockedOpenTasks => write!(f, "blocked_open_tasks"),
107 Self::BlockedGateFailure => write!(f, "blocked_gate_failure"),
108 Self::MergeConflict => write!(f, "merge_conflict"),
109 Self::FailedPolicyDenial => write!(f, "failed_policy_denial"),
110 Self::FailedRuntimeError => write!(f, "failed_runtime_error"),
111 Self::CancelledByOperator => write!(f, "cancelled_by_operator"),
112 Self::DrainedByOperator => write!(f, "drained_by_operator"),
113 Self::TimedOut => write!(f, "timed_out"),
114 Self::StalledNoProgress => write!(f, "stalled_no_progress"),
115 }
116 }
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
121#[serde(rename_all = "snake_case")]
122pub enum CancellationSource {
123 Operator,
124 Sigint,
125 Sigterm,
126 Sw4rmPreemption,
127 Unknown,
128}
129
130impl std::fmt::Display for CancellationSource {
131 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132 match self {
133 Self::Operator => write!(f, "operator"),
134 Self::Sigint => write!(f, "sigint"),
135 Self::Sigterm => write!(f, "sigterm"),
136 Self::Sw4rmPreemption => write!(f, "sw4rm_preemption"),
137 Self::Unknown => write!(f, "unknown"),
138 }
139 }
140}
141
142#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
144#[serde(rename_all = "snake_case")]
145pub enum CancellationActorKind {
146 Operator,
147 System,
148 Supervisor,
149 Unknown,
150}
151
152impl std::fmt::Display for CancellationActorKind {
153 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
154 match self {
155 Self::Operator => write!(f, "operator"),
156 Self::System => write!(f, "system"),
157 Self::Supervisor => write!(f, "supervisor"),
158 Self::Unknown => write!(f, "unknown"),
159 }
160 }
161}
162
163#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
165#[serde(rename_all = "snake_case")]
166pub enum CancellationStage {
167 Executing,
168 Retrying,
169 Verifying,
170 Unknown,
171}
172
173impl std::fmt::Display for CancellationStage {
174 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
175 match self {
176 Self::Executing => write!(f, "executing"),
177 Self::Retrying => write!(f, "retrying"),
178 Self::Verifying => write!(f, "verifying"),
179 Self::Unknown => write!(f, "unknown"),
180 }
181 }
182}
183
184#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
186pub struct CancellationProvenance {
187 pub cancellation_source: CancellationSource,
188 #[serde(default)]
189 pub signal_name: Option<String>,
190 #[serde(default)]
191 pub signal_number: Option<i32>,
192 #[serde(default)]
193 pub sender_pid: Option<u32>,
194 #[serde(default)]
195 pub receiver_pid: Option<u32>,
196 #[serde(default)]
197 pub parent_pid: Option<u32>,
198 #[serde(default)]
199 pub process_group_id: Option<u32>,
200 #[serde(default)]
201 pub session_id: Option<u32>,
202 #[serde(default)]
203 pub tty: Option<String>,
204 #[serde(default)]
205 pub actor_kind: Option<CancellationActorKind>,
206 #[serde(default)]
207 pub actor_detail: Option<String>,
208 #[serde(default)]
209 pub stage: Option<CancellationStage>,
210}
211
212#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
214#[serde(rename_all = "snake_case")]
215pub enum SafeMode {
216 Observe,
218 Execute,
220 Restricted,
222 Breakglass,
224}
225
226#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
228#[serde(rename_all = "snake_case")]
229pub enum CommandClass {
230 Io,
231 Cpu,
232 Git,
233 Tool,
234}