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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
//! # Maturity Model for Engineering Metrics Programs
//!
//! A metrics program's overall maturity is scored across five dimensions:
//! **governance**, **instrumentation**, **outcome balance**, **cultural
//! trust**, and **continuous improvement**, each independently on a 1–5
//! level scale (Level 1, Initiate, through Level 5, Orchestrate). The
//! chapter's central recommendation is to take the *minimum* across
//! dimensions as the honest overall score, resisting the temptation to
//! average them into a more flattering composite.
//!
//! ## Formula
//!
//! ```text
//! Honest overall score = minimum(governance, instrumentation, outcome balance,
//! cultural trust, continuous improvement)
//! (Average is computed alongside it only to make the gap visible.)
//! ```
//!
//! ## Why it matters
//!
//! A programme with excellent instrumentation (Level 4) but weak cultural
//! trust (Level 1) is not, in any meaningful sense, a Level 2 or 3
//! programme; the weak dimension actively undermines the value of the
//! strong ones, since untrustworthy data corrupted by fear-driven gaming is
//! not rescued by having been collected with excellent instrumentation.
//! Reporting the minimum, even though it produces a less flattering overall
//! picture than an average would, is what keeps the assessment honest.
//!
//! ## Example
//!
//! ```rust
//! use software_engineering::maturity_model::{
//! MaturityDimension, minimum_maturity_level, average_maturity_level,
//! };
//!
//! // Instrumentation through continuous improvement score well, but
//! // cultural trust lags badly.
//! let scored: [(MaturityDimension, u8); 5] = [
//! (MaturityDimension::Governance, 4),
//! (MaturityDimension::Instrumentation, 4),
//! (MaturityDimension::OutcomeBalance, 4),
//! (MaturityDimension::CulturalTrust, 1),
//! (MaturityDimension::ContinuousImprovement, 4),
//! ];
//! let scores: Vec<u8> = scored.iter().map(|(_, level)| *level).collect();
//!
//! let honest_score = minimum_maturity_level(&scores).unwrap();
//! let flattering_average = average_maturity_level(&scores).unwrap();
//! assert_eq!(honest_score, 1);
//! assert!((flattering_average - 3.4).abs() < 1e-9);
//! assert!((flattering_average as f64) > (honest_score as f64));
//! ```
//!
//! ## Pitfalls
//!
//! - **Averaging the five dimension scores** into a single, more flattering
//! composite, instead of reporting the minimum — hides exactly the weak
//! dimension that undermines the rest.
//! - **Assessing only aspirationally**, based on stated policy rather than
//! concrete evidence for each dimension.
//! - **Reassessing only after a crisis** forces the question reactively,
//! rather than on a fixed, regular cadence.
//! - **Treating a low score as a verdict to feel bad about**, rather than
//! the diagnostic starting point for a targeted investment plan.
//!
//! ## Sources
//!
//! - Chapter 8.4, Maturity model for engineering metrics programs.
//! - *Capability Maturity Model Integration (CMMI)*, Software Engineering
//! Institute (structural inspiration).
//!
//! Topic doc: software-engineering-metrics/locales/en-001/chapters/08-04-maturity-model-for-engineering-metrics-programs.md
/// One of the five maturity-model dimensions, in the chapter's own order.
/// The minimum score across a set of per-dimension maturity levels — the
/// chapter's recommended honest overall score.
///
/// Each score is expected to be in `1..=5`, but this function itself simply
/// takes the minimum of whatever values are given; validating the range is
/// the caller's responsibility.
///
/// # Arguments
///
/// * `scores` — one maturity level per dimension assessed.
///
/// # Returns
///
/// The minimum level, or `None` if `scores` is empty.
///
/// # Examples
///
/// ```rust
/// use software_engineering::maturity_model::minimum_maturity_level;
///
/// assert_eq!(minimum_maturity_level(&[4, 4, 4, 1, 4]), Some(1));
/// assert_eq!(minimum_maturity_level(&[]), None);
/// ```
/// The arithmetic mean across a set of per-dimension maturity levels — the
/// more flattering composite the chapter explicitly warns against using as
/// the *overall* score. Kept here so callers can compute it alongside
/// [`minimum_maturity_level`] and see the gap between the two.
///
/// # Arguments
///
/// * `scores` — one maturity level per dimension assessed.
///
/// # Returns
///
/// The mean level as an `f64`, or `None` if `scores` is empty.
///
/// # Examples
///
/// ```rust
/// use software_engineering::maturity_model::average_maturity_level;
///
/// let average = average_maturity_level(&[4, 4, 4, 1, 4]).unwrap();
/// assert!((average - 3.4).abs() < 1e-9);
/// assert_eq!(average_maturity_level(&[]), None);
/// ```