1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! Finding DTOs and longitudinal trend classification.
//!
//! Why: profiling has to name the code-quality issues it observes, but the
//! review pipeline's own `Finding` carries verdict-gate state — citation flags,
//! verification outcome, issue eligibility — that profiling never reads.
//! Reusing it would put trusty-review's review contract on tga's critical path,
//! which is the dependency edge #5468 exists to reverse, so tga owns its own
//! minimal DTO instead.
//! What: defines [`Effort`], [`Finding`], [`TrendTag`], and
//! [`LongitudinalFinding`].
//! Test: `finding_confidence_is_clamped`, `trend_tag_serde_roundtrip`, and
//! `longitudinal_finding_serde_roundtrip` in the parent `types` test module.
use ;
// ─── Effort ───────────────────────────────────────────────────────────────────
/// Estimated remediation effort for a [`Finding`].
///
/// Serialised as lowercase (`"low"`, `"medium"`, `"high"`).
// ─── Finding ──────────────────────────────────────────────────────────────────
/// A single code-quality observation attributed to a contributor's commits.
///
/// Why: the narrative pass and the Markdown report both need the same flat,
/// serialisable shape, and the profile JSON is a stored artefact — so the field
/// set is deliberately small and stable rather than mirroring whatever the
/// review pipeline currently tracks.
/// What: file, category, description, suggestion, a `[0.0, 1.0]` confidence,
/// and an [`Effort`] estimate.
/// Test: `finding_confidence_is_clamped`.
// ─── TrendTag ─────────────────────────────────────────────────────────────────
/// How a finding moved across the profiled periods.
///
/// Why: "you have 40 findings" is not actionable; "this one has recurred in
/// every period since January" is. The tag is what lets the report separate a
/// standing habit from a one-off.
/// What: four variants, serialised as `snake_case`.
/// Test: `trend_tag_serde_roundtrip`.
// ─── LongitudinalFinding ──────────────────────────────────────────────────────
/// A [`Finding`] bound to the period it was observed in, plus its trend.
///
/// `trend_tag` is `None` until `assign_trend_tags` has seen every period.