metrics

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 7, 2026 License: GPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package metrics provides agile metrics calculations.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FilterOutliers

func FilterOutliers(values []int, stddevs float64) []int

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

func WeekStart(t time.Time) time.Time

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

func WorkThreadsForPercentile(totalWorkThreads, percentile int) int

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL