fallow_output/health_diagnostics.rs
1/// Detailed timing breakdown for the health pipeline.
2///
3/// Only populated when `--performance` is passed.
4#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
5pub struct HealthTimings {
6 /// Wall-clock time of config loading, in milliseconds.
7 pub config_ms: f64,
8 /// Wall-clock time of file discovery, in milliseconds.
9 pub discover_ms: f64,
10 /// Wall-clock time of the parse stage, in milliseconds.
11 pub parse_ms: f64,
12 /// Summed wall-clock time of the actual AST parses across all rayon
13 /// workers (the parse stage's CPU cost). `parse_ms` is the stage's
14 /// wall-clock time. Observational and non-deterministic; do not assert
15 /// against it. `0.0` when `shared_parse` is true (parse was reused).
16 pub parse_cpu_ms: f64,
17 /// Wall-clock time of complexity scoring, in milliseconds.
18 pub complexity_ms: f64,
19 /// Wall-clock time of per-file maintainability scoring, in milliseconds.
20 pub file_scores_ms: f64,
21 /// Wall-clock time of git churn collection, in milliseconds.
22 pub git_churn_ms: f64,
23 /// True when churn data came from the on-disk churn cache.
24 pub git_churn_cache_hit: bool,
25 /// Bytes of `git log` output that the churn stage read. Exact for a given
26 /// repository, commit, churn window and date: commits move out of a
27 /// relative window as the date changes. Zero when the churn cache or a
28 /// churn file supplied all the history.
29 pub git_log_bytes: u64,
30 /// Wall-clock time of hotspot ranking, in milliseconds.
31 pub hotspots_ms: f64,
32 /// Wall-clock time of duplication analysis, in milliseconds.
33 pub duplication_ms: f64,
34 /// Wall-clock time of refactoring-target ranking, in milliseconds.
35 pub targets_ms: f64,
36 /// Wall-clock time of the whole health pipeline, in milliseconds.
37 pub total_ms: f64,
38 /// True when discover + parse were reused from the upstream dead-code
39 /// (check) pass in combined mode, so their timings are `0.0` here and
40 /// the cost is attributed to the `Pipeline Performance` table instead.
41 /// The renderer shows those two stages as `(measured above)`.
42 pub shared_parse: bool,
43}
44
45/// Framework-specific health detector coverage surfaced for agent consumers.
46#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
47#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
48pub struct FrameworkHealthDiagnostics {
49 /// Detected framework IDs, sorted and deduplicated.
50 pub detected_frameworks: Vec<String>,
51 /// Detector coverage for the detected frameworks.
52 pub detectors: Vec<FrameworkHealthDetector>,
53}
54
55/// Status for one framework-specific health detector.
56#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
57#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
58pub struct FrameworkHealthDetector {
59 /// Rule or detector ID, matching fallow's stable rule names where possible.
60 pub id: String,
61 /// Framework ID that made this detector relevant.
62 pub framework: String,
63 /// Whether the detector ran, was disabled, abstained, or could not be checked.
64 pub status: FrameworkHealthDetectorStatus,
65 /// Stable reason code for non-active statuses.
66 #[serde(default, skip_serializing_if = "Option::is_none")]
67 pub reason: Option<String>,
68}
69
70/// Detector status codes for framework health observability.
71#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
72#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
73#[serde(rename_all = "snake_case")]
74pub enum FrameworkHealthDetectorStatus {
75 /// Detector ran on this analysis.
76 Active,
77 /// Detector was turned off by configuration.
78 DisabledByConfig,
79 /// Detector ran but declined to report for this project.
80 Abstained,
81 /// Detector applicability could not be evaluated.
82 #[allow(dead_code, reason = "reserved for analysis paths that skip a detector")]
83 NotChecked,
84}