Class: CriticalChain

Inherits:
Object
  • Object
show all
Defined in:
lib/almirah/project/critical_chain.rb

Overview

The critical chain and project buffer for one decision group's Scope rows (ADR-195). This object serves two distinct jobs that want opposite treatment of completed work, so it keeps two views of the same Scope rows:

  • the scheduling chain (chain / buffer / projected_duration) excludes Done rows as finished work — you do not re-schedule what is already done — and reports the duration of the work still remaining;
  • the baseline chain (baseline_chain / baseline_buffer) keeps every row, Done included, as the plan was originally sized. Buffer-consumption accounting (the fever chart, ADR-196) reads this view so that a chain row which overran and then completed keeps consuming buffer instead of vanishing the moment it is marked Done, and so the consumption denominator stays a stable plan-time baseline rather than shrinking as rows finish (issue-207).

A predecessor outside the given set (a row in another group) drops out and is treated as an already-available input. The buffer aggregates the safety (safe - focused, clamped at 0) along a chain and cuts it by buffer_ratio, rounded up.

Instance Method Summary collapse

Constructor Details

#initialize(work_items, buffer_ratio: 0.5) ⇒ CriticalChain

Returns a new instance of CriticalChain.



63
64
65
66
67
68
69
# File 'lib/almirah/project/critical_chain.rb', line 63

def initialize(work_items, buffer_ratio: 0.5)
  @all_items = work_items
  @items = work_items.reject(&:done?)
  @buffer_ratio = buffer_ratio
  @scheduler = ChainScheduler.new(@items)
  @baseline_scheduler = ChainScheduler.new(@all_items)
end

Instance Method Details

#baseline_bufferObject

The plan-time buffer over the full baseline chain — the stable denominator for buffer-consumption %, unaffected by rows completing (issue-207).



95
96
97
# File 'lib/almirah/project/critical_chain.rb', line 95

def baseline_buffer
  buffer_for(baseline_chain)
end

#baseline_chainObject

The chain as originally planned, completed rows included (issue-207). Buffer consumption is accounted against this set so completed overruns stay visible.



79
80
81
# File 'lib/almirah/project/critical_chain.rb', line 79

def baseline_chain
  @baseline_scheduler.critical_chain
end

#bufferObject

ceil(buffer_ratio * Σ_chain max(safe - focused, 0)) over the remaining chain.



89
90
91
# File 'lib/almirah/project/critical_chain.rb', line 89

def buffer
  buffer_for(chain)
end

#chainObject

The remaining chain (Done rows excluded) in start order — drives the chain table and the projected completion of the work still to do.



73
74
75
# File 'lib/almirah/project/critical_chain.rb', line 73

def chain
  @scheduler.critical_chain
end

#estimated?Boolean

False when no row carries a positive focused estimate, so the overview marks the group "unestimated" rather than reporting a misleadingly short plan. Reads the baseline so a fully-completed group still reports as estimated and keeps its (100%-complete) fever chart instead of collapsing to "not sized".

Returns:

  • (Boolean)


107
108
109
# File 'lib/almirah/project/critical_chain.rb', line 107

def estimated?
  @all_items.any? { |wi| wi.focused_estimate.positive? }
end

#lengthObject

Chain length in working days (the latest finish).



84
85
86
# File 'lib/almirah/project/critical_chain.rb', line 84

def length
  @scheduler.makespan
end

#projected_durationObject



99
100
101
# File 'lib/almirah/project/critical_chain.rb', line 99

def projected_duration
  length + buffer
end