1use chrono::{DateTime, Utc};
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10pub struct DiagnosticObservation {
11 pub component: DiagnosticComponent,
12 pub scope: DiagnosticScope,
13 pub observed_at_utc: DateTime<Utc>,
16 pub basis: DiagnosticEvidenceBasis,
17 #[serde(default, skip_serializing_if = "Option::is_none")]
18 pub origin: Option<DiagnosticObservationOrigin>,
19 #[serde(default, skip_serializing_if = "Option::is_none")]
21 pub failure_category: Option<DiagnosticFailureCategory>,
22 #[serde(default, skip_serializing_if = "Option::is_none")]
23 pub next_action: Option<DiagnosticNextAction>,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
27#[serde(rename_all = "snake_case")]
28pub enum DiagnosticObservationOrigin {
29 RuntimeLogin,
30 SessionOpen,
31 Workflow,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
35#[serde(rename_all = "snake_case")]
36pub enum DiagnosticComponent {
37 Cli,
38 Filesystem,
39 Configuration,
40 ManagedRuntime,
41 TrustedRuntime,
42 Authentication,
43 Session,
44 Metadata,
45 Lake,
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
49#[serde(rename_all = "snake_case")]
50pub enum DiagnosticScope {
51 OwnerLogin,
53 Local,
55 OwnerSession,
57 SelectedPath,
59 WebRuntime,
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
64#[serde(rename_all = "snake_case")]
65pub enum DiagnosticEvidenceBasis {
66 LocalBuild,
67 LocalState,
69 LocalFilesystem,
70 ConfigurationOnly,
72 EndpointReachability,
74 ConnectionAttempt,
77 AuthenticatedAdapterObservation,
78 AuthenticatedServiceCompatibility,
81 HistoricalObservation,
83 NotChecked,
84}
85
86#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
89pub enum DiagnosticNextAction {
90 #[serde(rename = "ahri-tre doctor")]
91 Doctor,
92 #[serde(rename = "ahri-tre daemon doctor")]
93 DaemonDoctor,
94 #[serde(rename = "ahri-tre config preflight --help")]
96 ConfigPreflightHelp,
97 #[serde(rename = "ahri-tre auth status")]
98 AuthStatus,
99 #[serde(rename = "ahri-tre session status")]
100 SessionStatus,
101 #[serde(rename = "./dev-env local logs trusted-runtime")]
102 LocalTrustedRuntimeLogs,
103}
104
105#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
106pub struct DiagnosticFinding {
107 pub id: String,
108 #[serde(default, skip_serializing_if = "Option::is_none")]
109 pub component: Option<String>,
110 pub status: DiagnosticFindingStatus,
111 pub severity: DiagnosticFindingSeverity,
112 pub summary: String,
113 #[serde(default, skip_serializing_if = "Option::is_none")]
114 pub detail: Option<String>,
115 #[serde(default, skip_serializing_if = "Vec::is_empty")]
116 pub evidence: Vec<DiagnosticEvidence>,
117 #[serde(default, skip_serializing_if = "Option::is_none")]
118 pub observation: Option<DiagnosticObservation>,
119}
120
121#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
122#[serde(rename_all = "snake_case")]
123pub enum DiagnosticFindingStatus {
124 Passed,
125 Warning,
126 Failed,
127 Skipped,
128}
129
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
131#[serde(rename_all = "snake_case")]
132pub enum DiagnosticFindingSeverity {
133 Info,
134 Warning,
135 Error,
136}
137
138#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
139pub struct DiagnosticEvidence {
140 pub key: String,
141 pub value: String,
142}
143
144#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
146#[serde(rename_all = "snake_case")]
147pub enum DiagnosticFailureCategory {
148 Expired,
149 Unavailable,
150 Timeout,
151 Admission,
152 AuthorityUnavailable,
153 Connection,
154 Tls,
155 Authentication,
156 Compatibility,
157 Query,
158}
159
160#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
163#[serde(deny_unknown_fields)]
164pub struct OAuthArtifactObservation {
165 pub finding: DiagnosticFinding,
166 pub evaluated_at_utc: DateTime<Utc>,
167}