Skip to main content

ahri_tre_protocol/
diagnostics.rs

1//! Optional observation metadata for existing diagnostic reports.
2//!
3//! Evidence describes the authority and depth of an observation; it does not
4//! replace any surface's status or severity contract or authorize a probe.
5
6use 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    /// Time evidence was obtained, or the decision not to check was recorded.
14    /// Consumers must retain this time when presenting a saved report.
15    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    /// Closed adapter category, captured before private driver errors are flattened.
20    #[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    /// Evidence for the authenticated Runtime-login owner only.
52    OwnerLogin,
53    /// Observed within the local CLI process's authority only.
54    Local,
55    /// Evidence obtained within one authenticated owner's Session.
56    OwnerSession,
57    /// Only dependencies of the operator-selected Effective configuration.
58    SelectedPath,
59    /// Web's service-authenticated Runtime connection, never Datastore health.
60    WebRuntime,
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
64#[serde(rename_all = "snake_case")]
65pub enum DiagnosticEvidenceBasis {
66    LocalBuild,
67    /// Current local process or registry state, not dependency health.
68    LocalState,
69    LocalFilesystem,
70    /// Declared configuration; no dependency was contacted.
71    ConfigurationOnly,
72    /// Reachability only; does not establish authentication or adapter readiness.
73    EndpointReachability,
74    /// An attempted adapter connection/TLS or authentication exchange.
75    /// It does not establish usable authenticated adapter authority.
76    ConnectionAttempt,
77    AuthenticatedAdapterObservation,
78    /// Service authentication and the required protocol capabilities were checked.
79    /// This is not evidence of PostgreSQL, Lake, or end-user Session readiness.
80    AuthenticatedServiceCompatibility,
81    /// Retained prior evidence, never a newly performed check.
82    HistoricalObservation,
83    NotChecked,
84}
85
86/// Closed, release-owned command templates. No caller text can be interpolated.
87/// These are suggestions only; presenting a report never executes them.
88#[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    /// Help explains target selection without assuming an operator's authority.
95    #[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/// Closed safe failure categories for operator diagnostic evidence.
145#[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/// Owner-authorized, retained OAuth evidence. Evaluation advances independently
161/// of the finding's acquisition time and never implies remote validation.
162#[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}