Closure feels like progress until the numbers flatten. A dashboard that shows the day-by-day violation count with the ratio of each day to the previous makes a stall visible, and a simple extrapolation tells you roughly where it will stop, which decides whether a different strategy is needed.
v = [420, 260, 170, 130, 118, 112, 109]
ratios = [round(v[i + 1] / v[i], 3) for i in range(len(v) - 1)]
assert ratios == [0.619, 0.654, 0.765, 0.908, 0.949, 0.973]
stall_at = next(i for i in range(len(ratios) - 1) if ratios[i] >= 0.9 and ratios[i + 1] >= 0.9)
assert stall_at == 3 # ratios[3] and ratios[4] are both at or above 0.9
# extrapolate the floor from the last three differences (geometric decay of the differences)
d = [v[i + 1] - v[i] for i in range(len(v) - 3, len(v) - 1)] # last two differences: -6 and -3
q = d[1] / d[0]
floor = v[-1] + d[1] * q / (1 - q)
assert d == [-6, -3] and q == 0.5 and floor == 106.0
print("PASS: ratios", ratios, "; stall detected from day", stall_at + 1, "; projected floor about", floor)Day | Violations | Ratio to previous day |
|---|---|---|
0 | 420 | — |
1 | 260 | 0.619 |
2 | 170 | 0.654 |
3 | 130 | 0.765 |
4 | 118 | 0.908 |
5 | 112 | 0.949 |
6 | 109 | 0.973 |
Violations fall from 420 to 109, but the day-to-day ratio rises from 0.62 to 0.97: each day removes a smaller share. Two consecutive days with a ratio of at least 0.9 (days 4 and 5) flag a stall. Extrapolating the last differences (-6, then -3, a ratio of 0.5) puts the floor near 106 violations, about a quarter of where closure started. Waiting will not reach zero; the remaining violations need a different kind of fix: structural changes, a change of the method, or an agreed waiver with evidence. The extrapolation is rough, but the decision it supports is not.
Metric | Why |
|---|---|
Violations (union) per day, setup and hold separately | The progress series |
Ratio to previous day and the stall flag | Early warning |
ECOs applied per day and new violations they caused | Breakage rate |
Endpoints with negative setup-plus-hold sum | Candidates for structural fixes |
Near-critical histogram | Exposure to small changes |
The same definitions every day, so the series is comparable (union counts, same scenarios).
A stall triggers a decision, not more of the same: structural fix, method change, or waiver.
The dashboard distinguishes fixed from waived from open.
q = -2 / -8 = 0.25; floor = 100 + (-2) × 0.25 / 0.75 = 99.3 violations.