FAILURE MAP
← Case archive

FA-94021 / Shift rostering labor rules / Open access

Night period truncated at midnight · case 01

Only 23:00-24:00 counts as night; early morning hours are lost.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The window end is set to midnight rather than 06:00 the next day.

VERIFIED REPAIR

The night window ends 1800 minutes after its day start.

Unsuccessful approach: Wrapping 06:00 as a clock time produces an end before the start, so no night minutes count.

Case contract

A shift [start, end] in absolute minutes (day 0 starts at minute 0) and a night-shift threshold. The night period runs 23:00 to 06:00 across midnight. Return [night minutes, whether night minutes reach the threshold].

Why this case matters

Night-work classification drives night-worker limits and premiums and must handle shifts that start after midnight.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(shift, threshold):
    s, e = shift
    night = 0
    for d in range(s // 1440 - 1, e // 1440 + 1):
        lo = d * 1440 + 1380
        hi = d * 1440 + 1440
        night += max(0, min(e, hi) - max(s, lo))
    return [night, night >= threshold]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: window clamped at midnight 1', [[120, 480], 180], [240, True]),
  ('regression variant: window clamped at midnight 2', [[1560, 2040], 120], [240, True]),
  ('partial repair guard 3', [[8580, 8820], 180], [240, True]),
  ('boundary control 4', [[1380, 1559], 180], [179, False]),
  ('boundary control 5', [[1320, 1800], 180], [420, True]),
  ('normal control 6', [[5880, 6600], 240], [240, True]),
  ('normal control 7', [[6120, 6600], 180], [0, False]),
  ('normal control 8', [[5580, 6300], 120], [420, True])],
 [('regression: window clamped at midnight 1', [[1320, 1800], 180], [420, True]),
  ('regression variant: window clamped at midnight 2', [[7200, 7920], 240], [360, True]),
  ('partial repair guard 3', [[4200, 4380], 180], [120, False]),
  ('boundary control 4', [[1800, 2400], 180], [0, False]),
  ('boundary control 5', [[900, 1410], 180], [30, False]),
  ('normal control 6', [[1800, 2400], 240], [0, False]),
  ('normal control 7', [[4280, 5141], 120], [400, True]),
  ('normal control 8', [[5760, 6000], 120], [240, True])],
 [('regression: window clamped at midnight 1', [[1380, 1560], 180], [180, True]),
  ('regression variant: window clamped at midnight 2', [[5880, 5910], 120], [30, False]),
  ('partial repair guard 3', [[2840, 3020], 240], [180, False]),
  ('boundary control 4', [[120, 480], 180], [240, True]),
  ('normal control 5', [[4200, 4920], 180], [420, True]),
  ('normal control 6', [[8600, 8710], 240], [110, False]),
  ('normal control 7', [[1576, 2176], 120], [224, True]),
  ('normal control 8', [[1500, 1560], 180], [60, False])],
 [('regression: window clamped at midnight 1', [[1380, 1559], 180], [179, False]),
  ('regression variant: window clamped at midnight 2', [[6060, 6300], 180], [60, False]),
  ('partial repair guard 3', [[8051, 8771], 180], [191, True]),
  ('boundary control 4', [[2940, 3300], 240], [300, True]),
  ('normal control 5', [[4200, 4920], 180], [420, True]),
  ('normal control 6', [[1320, 1496], 180], [116, False]),
  ('normal control 7', [[6660, 7369], 120], [229, True]),
  ('normal control 8', [[3780, 4500], 120], [240, True])],
 [('regression: window clamped at midnight 1', [[2940, 3300], 240], [300, True]),
  ('regression variant: window clamped at midnight 2', [[5820, 6000], 180], [180, True]),
  ('partial repair guard 3', [[1783, 1813], 120], [17, False]),
  ('boundary control 4', [[1320, 1800], 180], [420, True]),
  ('boundary control 5', [[1800, 2400], 180], [0, False]),
  ('normal control 6', [[1440, 2253], 180], [360, True]),
  ('normal control 7', [[4200, 4230], 180], [0, False]),
  ('normal control 8', [[4260, 4860], 240], [420, True])]]
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 fixtureActualExpectedOutcome
regression: window clamped at midnight 1[0, False][240, True]Failed
regression variant: window clamped at midnight 2[0, False][240, True]Failed
partial repair guard 3[60, False][240, True]Failed
boundary control 4[60, False][179, False]Failed
boundary control 5[60, False][420, True]Failed
normal control 6[0, False][240, True]Failed
normal control 7[0, False][0, False]Passed
normal control 8[60, False][420, True]Failed

SHA-256 / 7d512e30f412836b31c7278f9f47c9058a7de2a2f3ee14b187f860ec11f0c993

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(shift, threshold):
    s, e = shift
    night = 0
    for d in range(s // 1440 - 1, e // 1440 + 1):
        lo = d * 1440 + 1380
        hi = (d * 1440 + 1800) % 1440
        night += max(0, min(e, hi) - max(s, lo))
    return [night, night >= threshold]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: window clamped at midnight 1', [[120, 480], 180], [240, True]),
  ('regression variant: window clamped at midnight 2', [[1560, 2040], 120], [240, True]),
  ('partial repair guard 3', [[8580, 8820], 180], [240, True]),
  ('boundary control 4', [[1380, 1559], 180], [179, False]),
  ('boundary control 5', [[1320, 1800], 180], [420, True]),
  ('normal control 6', [[5880, 6600], 240], [240, True]),
  ('normal control 7', [[6120, 6600], 180], [0, False]),
  ('normal control 8', [[5580, 6300], 120], [420, True])],
 [('regression: window clamped at midnight 1', [[1320, 1800], 180], [420, True]),
  ('regression variant: window clamped at midnight 2', [[7200, 7920], 240], [360, True]),
  ('partial repair guard 3', [[4200, 4380], 180], [120, False]),
  ('boundary control 4', [[1800, 2400], 180], [0, False]),
  ('boundary control 5', [[900, 1410], 180], [30, False]),
  ('normal control 6', [[1800, 2400], 240], [0, False]),
  ('normal control 7', [[4280, 5141], 120], [400, True]),
  ('normal control 8', [[5760, 6000], 120], [240, True])],
 [('regression: window clamped at midnight 1', [[1380, 1560], 180], [180, True]),
  ('regression variant: window clamped at midnight 2', [[5880, 5910], 120], [30, False]),
  ('partial repair guard 3', [[2840, 3020], 240], [180, False]),
  ('boundary control 4', [[120, 480], 180], [240, True]),
  ('normal control 5', [[4200, 4920], 180], [420, True]),
  ('normal control 6', [[8600, 8710], 240], [110, False]),
  ('normal control 7', [[1576, 2176], 120], [224, True]),
  ('normal control 8', [[1500, 1560], 180], [60, False])],
 [('regression: window clamped at midnight 1', [[1380, 1559], 180], [179, False]),
  ('regression variant: window clamped at midnight 2', [[6060, 6300], 180], [60, False]),
  ('partial repair guard 3', [[8051, 8771], 180], [191, True]),
  ('boundary control 4', [[2940, 3300], 240], [300, True]),
  ('normal control 5', [[4200, 4920], 180], [420, True]),
  ('normal control 6', [[1320, 1496], 180], [116, False]),
  ('normal control 7', [[6660, 7369], 120], [229, True]),
  ('normal control 8', [[3780, 4500], 120], [240, True])],
 [('regression: window clamped at midnight 1', [[2940, 3300], 240], [300, True]),
  ('regression variant: window clamped at midnight 2', [[5820, 6000], 180], [180, True]),
  ('partial repair guard 3', [[1783, 1813], 120], [17, False]),
  ('boundary control 4', [[1320, 1800], 180], [420, True]),
  ('boundary control 5', [[1800, 2400], 180], [0, False]),
  ('normal control 6', [[1440, 2253], 180], [360, True]),
  ('normal control 7', [[4200, 4230], 180], [0, False]),
  ('normal control 8', [[4260, 4860], 240], [420, True])]]
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 fixtureActualExpectedOutcome
regression: window clamped at midnight 1[240, True][240, True]Passed
regression variant: window clamped at midnight 2[0, False][240, True]Failed
partial repair guard 3[0, False][240, True]Failed
boundary control 4[0, False][179, False]Failed
boundary control 5[0, False][420, True]Failed
normal control 6[0, False][240, True]Failed
normal control 7[0, False][0, False]Passed
normal control 8[0, False][420, True]Failed

SHA-256 / 52498d019b8c9ca4dff586d80a14369df3aae7e6873a019a903be246536afff4

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(shift, threshold):
    s, e = shift
    night = 0
    for d in range(s // 1440 - 1, e // 1440 + 1):
        lo = d * 1440 + 1380
        hi = d * 1440 + 1800
        night += max(0, min(e, hi) - max(s, lo))
    return [night, night >= threshold]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: window clamped at midnight 1', [[120, 480], 180], [240, True]),
  ('regression variant: window clamped at midnight 2', [[1560, 2040], 120], [240, True]),
  ('partial repair guard 3', [[8580, 8820], 180], [240, True]),
  ('boundary control 4', [[1380, 1559], 180], [179, False]),
  ('boundary control 5', [[1320, 1800], 180], [420, True]),
  ('normal control 6', [[5880, 6600], 240], [240, True]),
  ('normal control 7', [[6120, 6600], 180], [0, False]),
  ('normal control 8', [[5580, 6300], 120], [420, True])],
 [('regression: window clamped at midnight 1', [[1320, 1800], 180], [420, True]),
  ('regression variant: window clamped at midnight 2', [[7200, 7920], 240], [360, True]),
  ('partial repair guard 3', [[4200, 4380], 180], [120, False]),
  ('boundary control 4', [[1800, 2400], 180], [0, False]),
  ('boundary control 5', [[900, 1410], 180], [30, False]),
  ('normal control 6', [[1800, 2400], 240], [0, False]),
  ('normal control 7', [[4280, 5141], 120], [400, True]),
  ('normal control 8', [[5760, 6000], 120], [240, True])],
 [('regression: window clamped at midnight 1', [[1380, 1560], 180], [180, True]),
  ('regression variant: window clamped at midnight 2', [[5880, 5910], 120], [30, False]),
  ('partial repair guard 3', [[2840, 3020], 240], [180, False]),
  ('boundary control 4', [[120, 480], 180], [240, True]),
  ('normal control 5', [[4200, 4920], 180], [420, True]),
  ('normal control 6', [[8600, 8710], 240], [110, False]),
  ('normal control 7', [[1576, 2176], 120], [224, True]),
  ('normal control 8', [[1500, 1560], 180], [60, False])],
 [('regression: window clamped at midnight 1', [[1380, 1559], 180], [179, False]),
  ('regression variant: window clamped at midnight 2', [[6060, 6300], 180], [60, False]),
  ('partial repair guard 3', [[8051, 8771], 180], [191, True]),
  ('boundary control 4', [[2940, 3300], 240], [300, True]),
  ('normal control 5', [[4200, 4920], 180], [420, True]),
  ('normal control 6', [[1320, 1496], 180], [116, False]),
  ('normal control 7', [[6660, 7369], 120], [229, True]),
  ('normal control 8', [[3780, 4500], 120], [240, True])],
 [('regression: window clamped at midnight 1', [[2940, 3300], 240], [300, True]),
  ('regression variant: window clamped at midnight 2', [[5820, 6000], 180], [180, True]),
  ('partial repair guard 3', [[1783, 1813], 120], [17, False]),
  ('boundary control 4', [[1320, 1800], 180], [420, True]),
  ('boundary control 5', [[1800, 2400], 180], [0, False]),
  ('normal control 6', [[1440, 2253], 180], [360, True]),
  ('normal control 7', [[4200, 4230], 180], [0, False]),
  ('normal control 8', [[4260, 4860], 240], [420, True])]]
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 fixtureActualExpectedOutcome
regression: window clamped at midnight 1[240, True][240, True]Passed
regression variant: window clamped at midnight 2[240, True][240, True]Passed
partial repair guard 3[240, True][240, True]Passed
boundary control 4[179, False][179, False]Passed
boundary control 5[420, True][420, True]Passed
normal control 6[240, True][240, True]Passed
normal control 7[0, False][0, False]Passed
normal control 8[420, True][420, True]Passed

SHA-256 / 52024a6344192edcd672fc623f2983ae5d3ab98edce8749b649561f02f46e28c

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.634507+00:00.

Case digest / 7b843dcd73480a00950918716a6176c012358401ae73582e0324e5f1b62c05a1