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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
//! # On-Call, Capacity, and Operational Load Metrics
//!
//! On-call load often concentrates on a small number of experienced people
//! who can resolve incidents fastest — the same pattern this book warns
//! against for code review load and knowledge concentration elsewhere,
//! applied here to operational burden. A team-wide average page frequency
//! can hide this concentration entirely; measuring the busiest individual's
//! share, and how often any one person is on call relative to a sustainable
//! limit, surfaces the burnout and bus-factor risk a simple average cannot.
//!
//! ## Formula
//!
//! ```text
//! Paging concentration (%) = busiest engineer's pages / total pages × 100
//! On-call frequency ratio = weeks on call / total weeks
//! Exceeds sustainable frequency when on-call frequency ratio > max ratio
//! (commonly 0.25, "no more than one week in four")
//! ```
//!
//! ## Why it matters
//!
//! Rebalancing rotations deliberately, once concentration appears, depends
//! on actually measuring individual-level page distribution rather than
//! only a team-wide average — the average can look entirely reasonable
//! while two or three people effectively carry the rotation due to skill
//! gaps or availability constraints. Aggregate this data at the team level
//! to inform staffing and hiring decisions; never use individual
//! page-response metrics to evaluate a specific engineer's performance.
//!
//! ## Example
//!
//! ```rust
//! use software_engineering::on_call_metrics::{
//! paging_concentration_percent, on_call_frequency_ratio,
//! exceeds_sustainable_on_call_frequency,
//! };
//!
//! // Of 40 pages across the team last quarter, the busiest engineer took 22.
//! let concentration = paging_concentration_percent(22.0, 40.0).unwrap();
//! assert!((concentration - 55.0).abs() < 1e-9);
//!
//! // That same engineer was on call 6 of the last 12 weeks: one week in two,
//! // well past the "no more than one week in four or five" guideline.
//! let ratio = on_call_frequency_ratio(6.0, 12.0).unwrap();
//! assert_eq!(ratio, 0.5);
//! assert_eq!(exceeds_sustainable_on_call_frequency(6.0, 12.0, 0.25), Some(true));
//! ```
//!
//! ## Pitfalls
//!
//! - **Reporting only a team-wide average page frequency** — hides severe
//! individual concentration that drives both burnout and bus-factor risk.
//! - **Treating a nominally adequate rotation roster as sufficient** without
//! checking whether it effectively relies on only two or three people due
//! to skill gaps or availability constraints.
//! - **Measuring only active incident time**, ignoring the psychological
//! cost of being on call even during a shift with zero pages.
//! - **Using individual page-response metrics to evaluate a specific
//! engineer** — the goal is sustainable staffing and system design, never
//! individual scorekeeping.
//!
//! ## Sources
//!
//! - Chapter 6.3, On-call, capacity, and operational load metrics.
//!
//! Topic doc: software-engineering-metrics/locales/en-001/chapters/06-03-on-call-capacity-and-operational-load-metrics.md
/// Paging concentration: how much of the team's total paging load fell on
/// the single busiest on-call engineer.
///
/// `busiest_engineer_pages / total_pages × 100`.
///
/// # Arguments
///
/// * `busiest_engineer_pages` — count of pages received by the busiest
/// individual engineer.
/// * `total_pages` — total count of pages received by the whole team.
///
/// # Returns
///
/// The concentration as a percentage, or `None` if `total_pages` is zero.
///
/// # Examples
///
/// ```rust
/// use software_engineering::on_call_metrics::paging_concentration_percent;
///
/// assert!((paging_concentration_percent(22.0, 40.0).unwrap() - 55.0).abs() < 1e-9);
/// assert_eq!(paging_concentration_percent(1.0, 0.0), None);
/// ```
/// On-call frequency ratio: the fraction of weeks an engineer spent on
/// call.
///
/// `weeks_on_call / total_weeks`.
///
/// # Arguments
///
/// * `weeks_on_call` — count of weeks the engineer was on call.
/// * `total_weeks` — total number of weeks in the observation period.
///
/// # Returns
///
/// The ratio, or `None` if `total_weeks` is zero.
///
/// # Examples
///
/// ```rust
/// use software_engineering::on_call_metrics::on_call_frequency_ratio;
///
/// assert_eq!(on_call_frequency_ratio(6.0, 12.0), Some(0.5));
/// assert_eq!(on_call_frequency_ratio(1.0, 0.0), None);
/// ```
/// Whether an engineer's on-call frequency exceeds a given sustainable
/// maximum, such as the chapter's example of "no more than one week in four
/// or five" (a `max_ratio` of `0.25` or `0.20`).
///
/// # Arguments
///
/// * `weeks_on_call` — count of weeks the engineer was on call.
/// * `total_weeks` — total number of weeks in the observation period.
/// * `max_ratio` — the maximum sustainable on-call frequency ratio.
///
/// # Returns
///
/// `Some(true)` if the engineer's ratio exceeds `max_ratio`, `Some(false)`
/// otherwise, or `None` if `total_weeks` is zero.
///
/// # Examples
///
/// ```rust
/// use software_engineering::on_call_metrics::exceeds_sustainable_on_call_frequency;
///
/// // 6 of 12 weeks is one week in two, well past a one-in-four limit.
/// assert_eq!(exceeds_sustainable_on_call_frequency(6.0, 12.0, 0.25), Some(true));
/// // 3 of 12 weeks is exactly one week in four: not exceeding it.
/// assert_eq!(exceeds_sustainable_on_call_frequency(3.0, 12.0, 0.25), Some(false));
/// ```