flowcast design notes
1. From transitions to a timeline
Each issue is a list of (timestamp, from, to) status changes. flowcast turns it into contiguous segments, starting with the initial status at creation, and maps each status to a category: todo, active, waiting (in progress but idle) or done.
- started: the first time a segment enters
activeorwaiting. A reopen never resets it. - done_at: the start of the trailing run of
donesegments, or none if the item is currently open. - cycle time =
done_at - started; lead time =done_at - created; age =as_of - startedfor open in-progress items.
Worked example: In Progress Jan 2, Done Jan 3, reopened Jan 10, Done Jan 12. Started = Jan 2, done_at = Jan 12, cycle time 10 days. The reopen is part of the true time to deliver. If the item is currently reopened, done_at is none and it counts as aging work, not as throughput.
An item going To Do -> Done has no start. It is counted in throughput and lead time, excluded from cycle time, and reported as "skipped".
as_of truncates history: transitions after it are ignored and issues created after it vanish. Backtesting relies on this to rebuild exactly what was known at a past date.
2. Metrics
- Percentiles use linear interpolation. For
[1,2,3,4,5], P85 is4 + 0.4 = 4.4. - CFD: for each day the category of every issue at 23:59:59. Invariant:
todo + in_progress + doneequals the number of issues created so far. WIP is the in-progress band. - Flow efficiency = active days / cycle days over items finished in the window. In Progress 2d, Blocked 2d gives 50%. Per-status time shows where the waiting sits.
- Little's Law: average WIP should equal throughput x average cycle time in a stable system. The check reports the ratio and calls 0.75 to 1.25 consistent; outside that, the process is changing (growing backlog, batch releases) and forecasts deserve less trust.
- Aging compares open items with the cycle times of items finished in the window.
3. Monte Carlo forecasting
History is the number of items finished on each working day in the window. Completions on weekends or holidays are folded back onto the previous working day, so no throughput is lost while those days still are not sampled as future capacity.
How many by date D: each run draws one history value per working day until D (using the working day calendar) and sums them. Confidence is the share of runs that reached at least the value, so P85 is the 15th percentile of outcomes. For a constant history [2] and 7 days every run gives 14.
When will N be done: each run draws days until the cumulative count reaches N; the date is that many working days after the as-of date. P85 is the 85th percentile of run lengths. With history [2] and N=9, every run takes 5 days (2,4,6,8,10).
Scope growth: per run a multiplier m >= 1 is drawn and the target becomes ceil(N*m). The multiplier is uniform in a user range (--split-rate 1.0-1.3) or bootstrapped from epics (--split-history): for each epic, final item count / items created in its first 14 days. An epic that planned 20 items and ended with 32 contributes 1.6.
Teams and epics: each group is sampled with its own seeded random stream (seed:group), so adding a group never changes another group's numbers. Team totals combine paired runs (sum of items, or the max of finish times, i.e. the last team to finish). Epics share the combined throughput and the total is simulated for the summed backlog.
Reproducibility: the same seed and data give the same answer. Convergence is tested: the mean of a uniform history converges to the analytic mean, and P85 from different seeds at 10k runs differs by at most one item.
4. Backtesting
For weekly origins d (after one window of history, with the horizon fully observed): rebuild timelines as of d, take the trailing window of throughput, forecast "items finished in the next H working days" at P50/P85/P95, then count what was actually finished. The hit rate at confidence c is the share of origins where actual >= forecast. Healthy values are close to c. Much lower means the process was less predictable than its history suggested; much higher means forecasts are conservative (also what you see during a ramp-up). The P50 error is the mean absolute percentage error of the median forecast.