Documentation
¶
Overview ¶
Package metrics provides agile metrics calculations.
Index ¶
- func FilterOutliers(values []int, stddevs float64) []int
- func FormatForecast(result *ForecastResult) string
- func GetWeeklyThroughputValues(result ThroughputResult) []int
- func WeekStart(t time.Time) time.Time
- func WorkThreadsForPercentile(totalWorkThreads, percentile int) int
- type CycleTimeCalculator
- type CycleTimeResult
- type CycleTimeStats
- type ForecastResult
- type MonteCarloConfig
- type MonteCarloSimulator
- func (mc *MonteCarloSimulator) Run(remainingItems int) (*ForecastResult, error)
- func (mc *MonteCarloSimulator) RunMultiPercentile(remaining, totalWorkThreads int) (*ForecastResult, error)
- func (mc *MonteCarloSimulator) RunSequential(remainingItems []int) ([]*ForecastResult, error)
- func (mc *MonteCarloSimulator) RunSequentialMultiPercentile(remainingItems []int, totalWorkThreads int) ([]*ForecastResult, error)
- type StatsDays
- type ThroughputCalculator
- type ThroughputFrequency
- type ThroughputPeriod
- type ThroughputResult
- type ThroughputStats
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FilterOutliers ¶
FilterOutliers returns values within mean ± stddevs*σ. If all values would be filtered or len < 2, returns the original slice unchanged.
func FormatForecast ¶
func FormatForecast(result *ForecastResult) string
FormatForecast returns a human-readable forecast summary.
func GetWeeklyThroughputValues ¶
func GetWeeklyThroughputValues(result ThroughputResult) []int
GetWeeklyThroughputValues returns just the count values for Monte Carlo.
func WeekStart ¶
WeekStart returns the Monday of the ISO week containing t (at midnight). Use this to normalize a date range start before building JQL and calling Calculate, so the first bucket is always a full week.
func WorkThreadsForPercentile ¶
WorkThreadsForPercentile maps a confidence percentile to a work thread count given a total. Higher percentiles (more conservative) use fewer work threads to model less parallelism.
50th → totalWorkThreads (fully parallel — optimistic) 70th → ¾ × threads (floor) 85th → ½ × threads (ceiling) 95th → 1 (fully sequential — pessimistic)
Types ¶
type CycleTimeCalculator ¶
type CycleTimeCalculator struct {
// contains filtered or unexported fields
}
CycleTimeCalculator calculates cycle time metrics.
func NewCycleTimeCalculator ¶
func NewCycleTimeCalculator(mapper *workflow.Mapper) *CycleTimeCalculator
NewCycleTimeCalculator creates a new cycle time calculator.
func (*CycleTimeCalculator) Calculate ¶
func (c *CycleTimeCalculator) Calculate(histories []workflow.IssueHistory) []CycleTimeResult
Calculate computes cycle time for each completed issue.
func (*CycleTimeCalculator) CalculateInProgress ¶
func (c *CycleTimeCalculator) CalculateInProgress(histories []workflow.IssueHistory) []CycleTimeResult
CalculateInProgress computes cycle time for issues that have started but not yet completed, using now as the end point. Useful for surfacing long-running open work.
type CycleTimeResult ¶
type CycleTimeResult struct {
IssueKey string
IssueType string
Summary string
CycleTime time.Duration
StartDate time.Time
EndDate time.Time
InProgress bool // true when the issue has started but not yet completed
StageDetails map[string]time.Duration // Time spent in each stage
// Raw JIRA fields
Assignee string
Priority string
Labels []string
EpicKey string
}
CycleTimeResult holds cycle time calculation for a single issue.
func FilterCycleTimeOutliers ¶
func FilterCycleTimeOutliers(results []CycleTimeResult) (kept, outliers []CycleTimeResult)
FilterCycleTimeOutliers splits cycle time results into kept and outlier slices using Tukey's IQR fence method: outliers are values outside [Q1 - iqrFenceMultiplier×IQR, Q3 + iqrFenceMultiplier×IQR]. IQR is robust against the masking effect that afflicts stddev-based methods when multiple extreme values inflate σ and hide each other from the filter. If len < 4 or IQR is 0, returns everything in kept.
func (CycleTimeResult) CycleTimeDays ¶
func (r CycleTimeResult) CycleTimeDays() float64
CycleTimeDays returns cycle time in business days (float64).
type CycleTimeStats ¶
type CycleTimeStats struct {
Count int
Mean time.Duration
Median time.Duration
Percentile50 time.Duration
Percentile70 time.Duration
Percentile85 time.Duration
Percentile95 time.Duration
Min time.Duration
Max time.Duration
StdDev time.Duration
}
CycleTimeStats holds statistical summary of cycle times.
func CalculateStats ¶
func CalculateStats(results []CycleTimeResult) CycleTimeStats
CalculateStats computes statistical summary of cycle times.
func (CycleTimeStats) ToDays ¶
func (s CycleTimeStats) ToDays() StatsDays
ToDays converts CycleTimeStats to StatsDays.
type ForecastResult ¶
type ForecastResult struct {
TargetItems int
RemainingItems int
TrialsRun int
Percentiles map[int]time.Time // Percentile -> completion date
PercentileDays map[int]int // Percentile -> days from now
DeadlineDate *time.Time
DeadlineConfidence float64 // Probability of meeting deadline (0-1)
ThroughputSamples int // Number of throughput samples used
AvgThroughput float64 // Average weekly throughput
}
ForecastResult holds Monte Carlo simulation results.
type MonteCarloConfig ¶
type MonteCarloConfig struct {
Trials int // Number of simulations (default: 10000)
ThroughputWindow int // Days of history to sample from (default: 60)
SimulationStart time.Time // When to start simulation (default: now)
Deadline *time.Time // Optional deadline to check against
WorkThreads int // Number of issues the team works on in parallel; multiplies sampled weekly throughput (default: 1)
}
MonteCarloConfig configures the simulation.
func DefaultMonteCarloConfig ¶
func DefaultMonteCarloConfig() MonteCarloConfig
DefaultMonteCarloConfig returns sensible defaults.
type MonteCarloSimulator ¶
type MonteCarloSimulator struct {
// contains filtered or unexported fields
}
MonteCarloSimulator runs Monte Carlo simulations for forecasting.
func NewMonteCarloSimulator ¶
func NewMonteCarloSimulator(config MonteCarloConfig, weeklyThroughput []int) *MonteCarloSimulator
NewMonteCarloSimulator creates a simulator with historical throughput data.
func (*MonteCarloSimulator) Run ¶
func (mc *MonteCarloSimulator) Run(remainingItems int) (*ForecastResult, error)
Run executes the Monte Carlo simulation.
func (*MonteCarloSimulator) RunMultiPercentile ¶
func (mc *MonteCarloSimulator) RunMultiPercentile(remaining, totalWorkThreads int) (*ForecastResult, error)
RunMultiPercentile runs a separate simulation per confidence percentile, each with a work thread count determined by WorkThreadsForPercentile. The median (p50) of each per-thread simulation becomes that percentile's completion date.
When totalWorkThreads <= 1, falls back to the standard Run (percentiles from one distribution).
func (*MonteCarloSimulator) RunSequential ¶
func (mc *MonteCarloSimulator) RunSequential(remainingItems []int) ([]*ForecastResult, error)
RunSequential runs Monte Carlo simulations for a prioritized list of epics, treating work as sequential: each epic starts only after all prior epics complete. Returns one ForecastResult per epic in the same order as remainingItems.
func (*MonteCarloSimulator) RunSequentialMultiPercentile ¶
func (mc *MonteCarloSimulator) RunSequentialMultiPercentile(remainingItems []int, totalWorkThreads int) ([]*ForecastResult, error)
RunSequentialMultiPercentile is the sequential-epics equivalent of RunMultiPercentile. Each percentile uses the work thread count from WorkThreadsForPercentile; runs are cached by thread count to avoid redundant simulations.
When totalWorkThreads <= 1, falls back to RunSequential.
type StatsDays ¶
type StatsDays struct {
Count int
Mean float64
Median float64
Percentile50 float64
Percentile70 float64
Percentile85 float64
Percentile95 float64
Min float64
Max float64
StdDev float64
}
StatsDays returns stats in days for easier reading.
type ThroughputCalculator ¶
type ThroughputCalculator struct {
// contains filtered or unexported fields
}
ThroughputCalculator calculates throughput metrics.
func NewThroughputCalculator ¶
func NewThroughputCalculator(frequency ThroughputFrequency, mapper ...*workflow.Mapper) *ThroughputCalculator
NewThroughputCalculator creates a new throughput calculator. Pass a workflow.Mapper to apply the same In Progress filter used by cycle time: issues that never entered the start stage are excluded from the count.
func (*ThroughputCalculator) Calculate ¶
func (tc *ThroughputCalculator) Calculate(histories []workflow.IssueHistory, from, to time.Time) ThroughputResult
Calculate computes throughput over time periods.
type ThroughputFrequency ¶
type ThroughputFrequency string
ThroughputFrequency defines the aggregation period.
const ( FrequencyDaily ThroughputFrequency = "daily" FrequencyWeekly ThroughputFrequency = "weekly" FrequencyBiweekly ThroughputFrequency = "biweekly" FrequencyMonthly ThroughputFrequency = "monthly" )
type ThroughputPeriod ¶
type ThroughputPeriod struct {
PeriodStart time.Time // Start of the period
PeriodEnd time.Time // End of the period
Count int // Number of items completed
IssueKeys []string // Keys of completed issues
}
ThroughputPeriod represents throughput for a time period.
type ThroughputResult ¶
type ThroughputResult struct {
Periods []ThroughputPeriod
TotalCount int
AvgCount float64
Frequency ThroughputFrequency
}
ThroughputResult holds the complete throughput analysis.
type ThroughputStats ¶
type ThroughputStats struct {
Periods int
TotalItems int
AvgItems float64
MinItems int
MaxItems int
MedianItems int
}
ThroughputStats calculates statistical summary of throughput.
func CalculateThroughputStats ¶
func CalculateThroughputStats(result ThroughputResult) ThroughputStats
CalculateThroughputStats computes statistics from throughput result.