tokmd_analysis_effort/request.rs
1//! Request and control types for effort estimation.
2//!
3//! These types form the boundary between CLI/config plumbing and the effort
4//! engine. They are intentionally small and serializable in spirit:
5//!
6//! - `EffortModelKind` chooses the estimation strategy,
7//! - `EffortLayer` controls how much of the estimate is intended for presentation,
8//! - `DeltaInput` describes a base/head comparison window,
9//! - `EffortRequest` bundles the knobs needed by `build_effort_report`.
10//!
11//! The request surface is allowed to be ahead of the implementation surface.
12//! In other words, callers may be able to request models or uncertainty modes
13//! that are parsed and validated before every variant is fully implemented.
14
15use std::fmt::{Display, Formatter};
16
17/// Request object passed into the effort engine.
18///
19/// This is the computation-facing version of the CLI/config surface. It is
20/// intentionally explicit so the builder can remain deterministic and avoid
21/// reaching back into argument parsing layers.
22///
23/// Notes:
24/// - `model` selects the requested estimate family,
25/// - `layer` is presentation-oriented metadata,
26/// - `base_ref` / `head_ref` enable delta output,
27/// - Monte Carlo fields are carried here even if the current engine chooses to
28/// reject or ignore them while only deterministic paths are implemented.
29#[derive(Debug, Clone, PartialEq, Eq)]
30pub struct EffortRequest {
31 /// Estimation model requested by the caller.
32 pub model: EffortModelKind,
33 /// Requested presentation depth for effort output.
34 pub layer: EffortLayer,
35 /// Optional base reference for change-window estimation.
36 pub base_ref: Option<String>,
37 /// Optional head reference for change-window estimation.
38 pub head_ref: Option<String>,
39 /// Enable Monte Carlo uncertainty estimation.
40 pub monte_carlo: bool,
41 /// Monte Carlo sample count when uncertainty estimation is enabled.
42 pub mc_iterations: usize,
43 /// Optional deterministic seed for Monte Carlo.
44 pub mc_seed: Option<u64>,
45}
46
47impl Default for EffortRequest {
48 fn default() -> Self {
49 Self {
50 model: EffortModelKind::Cocomo81Basic,
51 layer: EffortLayer::Full,
52 base_ref: None,
53 head_ref: None,
54 monte_carlo: false,
55 mc_iterations: 10_000,
56 mc_seed: None,
57 }
58 }
59}
60
61/// Effort-estimation model requested by the caller.
62///
63/// `Cocomo81Basic` is the deterministic baseline.
64/// Other variants may be accepted by the request layer before the underlying
65/// engine fully implements them; those cases should fail clearly rather than
66/// silently degrading.
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub enum EffortModelKind {
69 Cocomo81Basic,
70 Cocomo2Early,
71 Ensemble,
72}
73
74impl EffortModelKind {
75 pub fn as_str(self) -> &'static str {
76 match self {
77 Self::Cocomo81Basic => "cocomo81-basic",
78 Self::Cocomo2Early => "cocomo2-early",
79 Self::Ensemble => "ensemble",
80 }
81 }
82}
83
84impl Display for EffortModelKind {
85 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
86 write!(f, "{}", self.as_str())
87 }
88}
89
90/// Requested presentation depth for effort output.
91///
92/// This is primarily a rendering hint:
93/// - `Headline` focuses on summary numbers,
94/// - `Why` adds explanatory context,
95/// - `Full` includes assumptions and optional delta details.
96///
97/// The engine may still compute richer data than the selected layer displays.
98#[derive(Debug, Clone, Copy, PartialEq, Eq)]
99pub enum EffortLayer {
100 Headline,
101 Why,
102 Full,
103}
104
105impl EffortLayer {
106 pub fn as_str(self) -> &'static str {
107 match self {
108 Self::Headline => "headline",
109 Self::Why => "why",
110 Self::Full => "full",
111 }
112 }
113}
114
115impl Display for EffortLayer {
116 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
117 write!(f, "{}", self.as_str())
118 }
119}
120
121/// Optional base/head comparison input for delta estimation.
122///
123/// When present, the effort engine may attach a delta section describing the
124/// blast radius and estimated effort impact of the change window.
125#[derive(Debug, Clone)]
126pub struct DeltaInput {
127 pub base_ref: String,
128 pub head_ref: String,
129}