FA-93981 / Shift rostering labor rules / Open access
Long callback truncated at the minimum guarantee · case 01
A four-hour callback is paid only three hours.
ROOT CAUSE
The window end ignores callbacks longer than the guarantee.
VERIFIED REPAIR
Window end is the later of callback end and start plus guarantee.
Unsuccessful approach: Adding the guarantee after the callback end overpays every callback.
Case contract
Callback work intervals [start, end] and a minimum guarantee in minutes. Sorted by start, each callback that does not start inside the current guarantee window opens a new window from its start to max(end, start + guarantee); a callback starting before the window end extends the window to its own end if later. Return [paid minutes as the sum of window lengths, window count].
Why this case matters
Callback and show-up minimum-pay rules routinely double pay or underpay when callbacks cluster.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(callbacks, guarantee):
paid = 0
windows = 0
win_start = win_end = None
for s, e in sorted(callbacks):
if win_end is not None and s < win_end:
win_end = max(win_end, e)
else:
if win_end is not None:
paid += win_end - win_start
win_start, win_end = s, s + guarantee
windows += 1
if win_end is not None:
paid += win_end - win_start
return [paid, windows]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: guarantee floor 1', [[[0, 240]], 180], [240, 1]),
('regression variant: guarantee floor 2', [[[1819, 1939], [1640, 1760], [1400, 1640]], 180], [539, 2]),
('partial repair guard 3', [[[1550, 1580], [2180, 2210], [1580, 1780], [1400, 1520]], 120], [470, 3]),
('boundary control 4', [[[0, 30], [180, 200]], 180], [360, 2]),
('normal control 5', [[[100, 300], [400, 520], [579, 609], [758, 998]], 120], [680, 4]),
('normal control 6', [[[240, 300], [0, 30], [330, 390]], 120], [270, 2]),
('normal control 7', [[[0, 200], [361, 421], [180, 380]], 120], [421, 1]),
('normal control 8', [[[190, 430], [100, 340]], 180], [330, 1])],
[('regression: guarantee floor 1', [[[0, 30], [481, 601], [181, 381], [661, 691]], 120], [560, 4]),
('regression variant: guarantee floor 2', [[[100, 130], [1120, 1150], [880, 1120], [700, 715]], 180],
[780, 4]),
('partial repair guard 3', [[[1430, 1490], [1400, 1430]], 240], [240, 1]),
('boundary control 4', [[], 180], [0, 0]), ('boundary control 5', [[[0, 30], [60, 400]], 180], [400, 1]),
('normal control 6', [[[0, 120], [181, 301]], 120], [240, 2]),
('normal control 7', [[[1640, 1880], [1400, 1460]], 120], [360, 2]),
('normal control 8', [[[100, 300], [220, 250], [190, 220]], 180], [200, 1])],
[('regression: guarantee floor 1', [[[1580, 1595], [1760, 1960], [1400, 1460]], 120], [440, 3]),
('regression variant: guarantee floor 2', [[[340, 370], [700, 820], [100, 130], [519, 719]], 120],
[541, 3]),
('partial repair guard 3', [[[100, 340]], 120], [240, 1]),
('boundary control 4', [[[0, 30], [179, 200]], 180], [200, 1]),
('boundary control 5', [[[0, 30]], 180], [180, 1]),
('normal control 6', [[[1579, 1699], [1759, 1774], [1400, 1430]], 240], [539, 2]),
('normal control 7', [[[100, 300]], 120], [200, 1]),
('normal control 8', [[[0, 120], [211, 241], [392, 452], [30, 230]], 120], [361, 2])],
[('regression: guarantee floor 1', [[[100, 130], [340, 460], [521, 721]], 120], [440, 3]),
('regression variant: guarantee floor 2', [[[1400, 1600], [2000, 2240]], 120], [440, 2]),
('partial repair guard 3', [[[160, 280], [760, 820], [130, 250], [100, 340]], 120], [360, 2]),
('boundary control 4', [[[300, 330], [0, 30]], 180], [360, 2]),
('boundary control 5', [[[0, 240]], 180], [240, 1]),
('normal control 6', [[[1400, 1520], [1550, 1580], [1640, 1670]], 240], [480, 2]),
('normal control 7', [[[1640, 1700], [1400, 1640], [1670, 1700]], 180], [420, 2]),
('normal control 8', [[[1400, 1600], [2271, 2286], [1581, 1596], [1671, 1791]], 120], [440, 3])],
[('regression: guarantee floor 1', [[[100, 340]], 120], [240, 1]),
('regression variant: guarantee floor 2', [[[1400, 1415], [1940, 2180], [1640, 1880], [2030, 2270]], 120],
[690, 3]),
('partial repair guard 3', [[[280, 295], [880, 1120], [100, 340]], 120], [480, 2]),
('boundary control 4', [[[0, 30], [180, 200]], 180], [360, 2]), ('boundary control 5', [[], 180], [0, 0]),
('normal control 6', [[[100, 300], [281, 341], [762, 962], [581, 821]], 240], [622, 2]),
('normal control 7', [[[1400, 1460], [1640, 1670]], 180], [360, 2]),
('normal control 8', [[[310, 510], [130, 190], [491, 731], [100, 115]], 240], [631, 1])]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: guarantee floor 1 | [180, 1] | [240, 1] | Failed |
| regression variant: guarantee floor 2 | [479, 2] | [539, 2] | Failed |
| partial repair guard 3 | [470, 3] | [470, 3] | Passed |
| boundary control 4 | [360, 2] | [360, 2] | Passed |
| normal control 5 | [480, 4] | [680, 4] | Failed |
| normal control 6 | [270, 2] | [270, 2] | Passed |
| normal control 7 | [360, 3] | [421, 1] | Failed |
| normal control 8 | [330, 1] | [330, 1] | Passed |
SHA-256 / 05368f49c9e09c48ad725e6c9c031bc97f388c6902777c99d1f7028142a069ae
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(callbacks, guarantee):
paid = 0
windows = 0
win_start = win_end = None
for s, e in sorted(callbacks):
if win_end is not None and s < win_end:
win_end = max(win_end, e)
else:
if win_end is not None:
paid += win_end - win_start
win_start, win_end = s, e + guarantee
windows += 1
if win_end is not None:
paid += win_end - win_start
return [paid, windows]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: guarantee floor 1', [[[0, 240]], 180], [240, 1]),
('regression variant: guarantee floor 2', [[[1819, 1939], [1640, 1760], [1400, 1640]], 180], [539, 2]),
('partial repair guard 3', [[[1550, 1580], [2180, 2210], [1580, 1780], [1400, 1520]], 120], [470, 3]),
('boundary control 4', [[[0, 30], [180, 200]], 180], [360, 2]),
('normal control 5', [[[100, 300], [400, 520], [579, 609], [758, 998]], 120], [680, 4]),
('normal control 6', [[[240, 300], [0, 30], [330, 390]], 120], [270, 2]),
('normal control 7', [[[0, 200], [361, 421], [180, 380]], 120], [421, 1]),
('normal control 8', [[[190, 430], [100, 340]], 180], [330, 1])],
[('regression: guarantee floor 1', [[[0, 30], [481, 601], [181, 381], [661, 691]], 120], [560, 4]),
('regression variant: guarantee floor 2', [[[100, 130], [1120, 1150], [880, 1120], [700, 715]], 180],
[780, 4]),
('partial repair guard 3', [[[1430, 1490], [1400, 1430]], 240], [240, 1]),
('boundary control 4', [[], 180], [0, 0]), ('boundary control 5', [[[0, 30], [60, 400]], 180], [400, 1]),
('normal control 6', [[[0, 120], [181, 301]], 120], [240, 2]),
('normal control 7', [[[1640, 1880], [1400, 1460]], 120], [360, 2]),
('normal control 8', [[[100, 300], [220, 250], [190, 220]], 180], [200, 1])],
[('regression: guarantee floor 1', [[[1580, 1595], [1760, 1960], [1400, 1460]], 120], [440, 3]),
('regression variant: guarantee floor 2', [[[340, 370], [700, 820], [100, 130], [519, 719]], 120],
[541, 3]),
('partial repair guard 3', [[[100, 340]], 120], [240, 1]),
('boundary control 4', [[[0, 30], [179, 200]], 180], [200, 1]),
('boundary control 5', [[[0, 30]], 180], [180, 1]),
('normal control 6', [[[1579, 1699], [1759, 1774], [1400, 1430]], 240], [539, 2]),
('normal control 7', [[[100, 300]], 120], [200, 1]),
('normal control 8', [[[0, 120], [211, 241], [392, 452], [30, 230]], 120], [361, 2])],
[('regression: guarantee floor 1', [[[100, 130], [340, 460], [521, 721]], 120], [440, 3]),
('regression variant: guarantee floor 2', [[[1400, 1600], [2000, 2240]], 120], [440, 2]),
('partial repair guard 3', [[[160, 280], [760, 820], [130, 250], [100, 340]], 120], [360, 2]),
('boundary control 4', [[[300, 330], [0, 30]], 180], [360, 2]),
('boundary control 5', [[[0, 240]], 180], [240, 1]),
('normal control 6', [[[1400, 1520], [1550, 1580], [1640, 1670]], 240], [480, 2]),
('normal control 7', [[[1640, 1700], [1400, 1640], [1670, 1700]], 180], [420, 2]),
('normal control 8', [[[1400, 1600], [2271, 2286], [1581, 1596], [1671, 1791]], 120], [440, 3])],
[('regression: guarantee floor 1', [[[100, 340]], 120], [240, 1]),
('regression variant: guarantee floor 2', [[[1400, 1415], [1940, 2180], [1640, 1880], [2030, 2270]], 120],
[690, 3]),
('partial repair guard 3', [[[280, 295], [880, 1120], [100, 340]], 120], [480, 2]),
('boundary control 4', [[[0, 30], [180, 200]], 180], [360, 2]), ('boundary control 5', [[], 180], [0, 0]),
('normal control 6', [[[100, 300], [281, 341], [762, 962], [581, 821]], 240], [622, 2]),
('normal control 7', [[[1400, 1460], [1640, 1670]], 180], [360, 2]),
('normal control 8', [[[310, 510], [130, 190], [491, 731], [100, 115]], 240], [631, 1])]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: guarantee floor 1 | [420, 1] | [240, 1] | Failed |
| regression variant: guarantee floor 2 | [539, 1] | [539, 2] | Failed |
| partial repair guard 3 | [530, 2] | [470, 3] | Failed |
| boundary control 4 | [210, 1] | [360, 2] | Failed |
| normal control 5 | [930, 3] | [680, 4] | Failed |
| normal control 6 | [330, 2] | [270, 2] | Failed |
| normal control 7 | [421, 1] | [421, 1] | Passed |
| normal control 8 | [420, 1] | [330, 1] | Failed |
SHA-256 / 3d1ec8d0b774f95280c5252f4947c0153013a3ceeed854c6f0f3ac2086a3131d
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(callbacks, guarantee):
paid = 0
windows = 0
win_start = win_end = None
for s, e in sorted(callbacks):
if win_end is not None and s < win_end:
win_end = max(win_end, e)
else:
if win_end is not None:
paid += win_end - win_start
win_start, win_end = s, max(e, s + guarantee)
windows += 1
if win_end is not None:
paid += win_end - win_start
return [paid, windows]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: guarantee floor 1', [[[0, 240]], 180], [240, 1]),
('regression variant: guarantee floor 2', [[[1819, 1939], [1640, 1760], [1400, 1640]], 180], [539, 2]),
('partial repair guard 3', [[[1550, 1580], [2180, 2210], [1580, 1780], [1400, 1520]], 120], [470, 3]),
('boundary control 4', [[[0, 30], [180, 200]], 180], [360, 2]),
('normal control 5', [[[100, 300], [400, 520], [579, 609], [758, 998]], 120], [680, 4]),
('normal control 6', [[[240, 300], [0, 30], [330, 390]], 120], [270, 2]),
('normal control 7', [[[0, 200], [361, 421], [180, 380]], 120], [421, 1]),
('normal control 8', [[[190, 430], [100, 340]], 180], [330, 1])],
[('regression: guarantee floor 1', [[[0, 30], [481, 601], [181, 381], [661, 691]], 120], [560, 4]),
('regression variant: guarantee floor 2', [[[100, 130], [1120, 1150], [880, 1120], [700, 715]], 180],
[780, 4]),
('partial repair guard 3', [[[1430, 1490], [1400, 1430]], 240], [240, 1]),
('boundary control 4', [[], 180], [0, 0]), ('boundary control 5', [[[0, 30], [60, 400]], 180], [400, 1]),
('normal control 6', [[[0, 120], [181, 301]], 120], [240, 2]),
('normal control 7', [[[1640, 1880], [1400, 1460]], 120], [360, 2]),
('normal control 8', [[[100, 300], [220, 250], [190, 220]], 180], [200, 1])],
[('regression: guarantee floor 1', [[[1580, 1595], [1760, 1960], [1400, 1460]], 120], [440, 3]),
('regression variant: guarantee floor 2', [[[340, 370], [700, 820], [100, 130], [519, 719]], 120],
[541, 3]),
('partial repair guard 3', [[[100, 340]], 120], [240, 1]),
('boundary control 4', [[[0, 30], [179, 200]], 180], [200, 1]),
('boundary control 5', [[[0, 30]], 180], [180, 1]),
('normal control 6', [[[1579, 1699], [1759, 1774], [1400, 1430]], 240], [539, 2]),
('normal control 7', [[[100, 300]], 120], [200, 1]),
('normal control 8', [[[0, 120], [211, 241], [392, 452], [30, 230]], 120], [361, 2])],
[('regression: guarantee floor 1', [[[100, 130], [340, 460], [521, 721]], 120], [440, 3]),
('regression variant: guarantee floor 2', [[[1400, 1600], [2000, 2240]], 120], [440, 2]),
('partial repair guard 3', [[[160, 280], [760, 820], [130, 250], [100, 340]], 120], [360, 2]),
('boundary control 4', [[[300, 330], [0, 30]], 180], [360, 2]),
('boundary control 5', [[[0, 240]], 180], [240, 1]),
('normal control 6', [[[1400, 1520], [1550, 1580], [1640, 1670]], 240], [480, 2]),
('normal control 7', [[[1640, 1700], [1400, 1640], [1670, 1700]], 180], [420, 2]),
('normal control 8', [[[1400, 1600], [2271, 2286], [1581, 1596], [1671, 1791]], 120], [440, 3])],
[('regression: guarantee floor 1', [[[100, 340]], 120], [240, 1]),
('regression variant: guarantee floor 2', [[[1400, 1415], [1940, 2180], [1640, 1880], [2030, 2270]], 120],
[690, 3]),
('partial repair guard 3', [[[280, 295], [880, 1120], [100, 340]], 120], [480, 2]),
('boundary control 4', [[[0, 30], [180, 200]], 180], [360, 2]), ('boundary control 5', [[], 180], [0, 0]),
('normal control 6', [[[100, 300], [281, 341], [762, 962], [581, 821]], 240], [622, 2]),
('normal control 7', [[[1400, 1460], [1640, 1670]], 180], [360, 2]),
('normal control 8', [[[310, 510], [130, 190], [491, 731], [100, 115]], 240], [631, 1])]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: guarantee floor 1 | [240, 1] | [240, 1] | Passed |
| regression variant: guarantee floor 2 | [539, 2] | [539, 2] | Passed |
| partial repair guard 3 | [470, 3] | [470, 3] | Passed |
| boundary control 4 | [360, 2] | [360, 2] | Passed |
| normal control 5 | [680, 4] | [680, 4] | Passed |
| normal control 6 | [270, 2] | [270, 2] | Passed |
| normal control 7 | [421, 1] | [421, 1] | Passed |
| normal control 8 | [330, 1] | [330, 1] | Passed |
SHA-256 / 37f834897d46d19d5309ca2fb90933e763eae312c4c9f087fccea80d3a8f4a2a
Verification & scope
Stipulated toy labor rule for a bounded roster model; it is not legal advice and does not claim conformance with any jurisdiction, award, or collective agreement. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:52:00.074650+00:00.
Case digest / 4f605554a259e95be036f3eabe4bc0cb7c05e5b0cac908e6467d744f6d946015