Estimation, forecasting & calibration
Estimation, forecasting & calibration
FastLinkIt uses PERT three-point estimates plus a Monte Carlo forecast to predict project completion dates with realistic uncertainty cones. Optional historical calibration nudges forecasts toward observed reality once you have a track record.
The PERT triple
For each work item, enter three numbers:
- Optimistic (O) — best-case hours
- Likely (L) — most-likely hours
- Pessimistic (P) — worst-case hours
The work-item editor shows a live readout under the inputs:
- Expected —
(O + 4L + P) / 6, the PERT mean - Std-dev —
(P − O) / 6, the PERT standard deviation - 85% confidence — mean + 1σ, an approximate P85 ceiling
A sanity warning fires when O ≤ L ≤ P doesn't hold (only after all three are filled, so you're not pestered mid-entry).
The forecast
For Waterfall / Agile projects, the engine runs a Monte Carlo simulation (10,000 iterations by default) across every non-done work item with at least one estimate. Each item's hours are sampled from a normal distribution centred on its PERT mean, summed per simulation, and reported as P50 / P80 / P95 hour totals plus projected completion dates.
Completion dates assume a single resource working Projects.DefaultHoursPerDay (default 6) on weekdays only. PTO / holidays / multi-resource teams are not modelled in v1.
Historical calibration
If you've completed enough work items, the editor's PERT readout gains a fourth pill — Calibrated — showing how your estimates have historically compared to actuals. Format: <calibrated-mean> hrs (1.40×, n=12) with a tooltip explaining the cohort.
How it works
For each completed work item with both an estimate and logged time, the engine computes:
ratio = sum(actual hours) / PERT-expected hours
It averages those ratios across a cohort to produce a fudge factor. A factor of 1.4 means past tasks ran 40% longer than estimated; 0.9 means estimators consistently overestimate by 10%.
The cohort fallback chain
- Per-(assignee, type) — most personal signal. Returns the average ratio across this user's past completions of the same type.
- Per-(project, type) — captures project-specific drag (legacy codebase, complex domain) when the assignee has no history.
- None — if neither cohort meets the minimum, the calibrated pill doesn't render and you see raw PERT only.
The minimum cohort size is 5 items by default — enough to distinguish chronic optimism from a single bad day. Below that, the engine falls through to the next scope.
Knobs (configured in appsettings.json under Projects)
| Setting | Default | Effect |
|---|---|---|
CalibrationMinimumSampleSize |
5 | Lower for small teams; raise for stronger signals |
CalibrationOutlierTrimPercent |
0.0 (off) | Set to 0.1 to drop top + bottom 10% before averaging — defends against one disaster yanking the mean |
CalibrationRecencyWeightingEnabled |
false | When on, fresh completions count 2× and fade linearly to 1× over the decay window |
CalibrationRecencyDecayDays |
365 | Decay window for recency weighting |
Defaults preserve the v1 average — flipping a knob doesn't silently shift live factors. You opt in to each refinement once you have history to feel the difference.
Forecast accuracy in practice
- The forecast is only as good as your estimates. Garbage in, garbage out.
- Calibration helps when your team has a consistent estimating bias (always optimistic, always over-cautious).
- Calibration doesn't help when estimates are wildly inconsistent — the variance in past ratios bleeds through, and the factor drifts toward 1×.
- Story points (Agile) don't feed into the engine yet — points → hours mapping is a future enhancement.
Related
- Working with work items
- Reports
- Sprints & burndown — different chart, different math