Skip to main content

perfgate_types/
repair_context.rs

1use crate::{Metric, Verdict, VerdictStatus};
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4use std::collections::BTreeMap;
5
6/// A machine-readable failure package for automated triage.
7#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
8#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
9pub struct RepairContextReceipt {
10    /// Schema identifier, always "perfgate.repair_context.v1".
11    pub schema: String,
12    /// Benchmark name associated with the check.
13    pub benchmark: String,
14    /// Verdict from the check/compare workflow.
15    pub verdict: Verdict,
16    /// Optional top-level status for quick routing.
17    pub status: VerdictStatus,
18    /// Breached metrics (warn/fail/skip due to policy) with thresholds and values.
19    pub breached_metrics: Vec<RepairMetricBreach>,
20    /// Path to compare receipt when available.
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub compare_receipt_path: Option<String>,
23    /// Path to report artifact.
24    pub report_path: String,
25    /// Optional profile artifact path.
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub profile_path: Option<String>,
28    /// Git metadata (if available).
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub git: Option<RepairGitMetadata>,
31    /// Changed files summary from git working tree.
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub changed_files: Option<ChangedFilesSummary>,
34    /// Optional OTel span identifiers.
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub otel_span: Option<OtelSpanIdentifiers>,
37    /// Suggested next actions for humans/agents.
38    pub recommended_next_commands: Vec<String>,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
42#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
43pub struct RepairMetricBreach {
44    pub metric: Metric,
45    pub status: String,
46    pub baseline: f64,
47    pub current: f64,
48    pub regression: f64,
49    pub fail_threshold: f64,
50    pub warn_threshold: f64,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
54#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
55pub struct RepairGitMetadata {
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub branch: Option<String>,
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub sha: Option<String>,
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
63#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
64pub struct ChangedFilesSummary {
65    pub file_count: u32,
66    pub files: Vec<String>,
67    pub file_count_by_top_level: BTreeMap<String, u32>,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
71#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
72pub struct OtelSpanIdentifiers {
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub trace_id: Option<String>,
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub span_id: Option<String>,
77}