FAILURE MAP
← Case archive

FA-94151 / Shift rostering labor rules / Open access

Seven-minute remainder rounds up to the next quarter hour · case 01

Punches exactly seven minutes past a quarter move forward, shifting paid time.

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

ROOT CAUSE

The round-down branch is strict at seven minutes.

VERIFIED REPAIR

Round down for remainders 0-7 and up for 8-14.

Unsuccessful approach: Rounding up without subtracting the remainder overshoots the next quarter.

Case contract

Scheduled [start, end] and raw punches in minutes. A punch in at most 7 minutes before the scheduled start is treated as the start; a punch out at most 7 minutes after the scheduled end is treated as the end. Then each time is rounded to the quarter hour: remainder 0-7 down, 8-14 up. Return [in, out, max(out - in, 0)].

Why this case matters

Punch rounding and grace periods must be neutral; asymmetric boundaries systematically underpay.

1 / The failure

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

N = 1
observations = []
def solve(sched, punch_in, punch_out):
    start, end = sched
    def q(t):
        r = t % 15
        return t - r if r < 7 else t + 15 - r
    i = start if 0 < start - punch_in <= 7 else punch_in
    o = end if 0 < punch_out - end <= 7 else punch_out
    i, o = q(i), q(o)
    return [i, o, max(o - i, 0)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: quarter hour midpoint 1', [[480, 960], 472, 968], [465, 975, 510]),
  ('regression variant: quarter hour midpoint 2', [[487, 997], 494, 998], [495, 990, 495]),
  ('partial repair guard 3', [[540, 1020], 548, 1025], [555, 1020, 465]),
  ('boundary control 4', [[480, 960], 488, 952], [495, 945, 450]),
  ('boundary control 5', [[480, 960], 487, 953], [480, 960, 480]),
  ('normal control 6', [[600, 840], 607, 840], [600, 840, 240]),
  ('normal control 7', [[480, 720], 488, 486], [495, 480, 0]),
  ('normal control 8', [[487, 727], 495, 734], [495, 720, 225])],
 [('regression: quarter hour midpoint 1', [[480, 960], 487, 953], [480, 960, 480]),
  ('regression variant: quarter hour midpoint 2', [[487, 727], 495, 732], [495, 720, 225]),
  ('partial repair guard 3', [[540, 1050], 554, 1072], [555, 1065, 510]),
  ('boundary control 4', [[480, 960], 473, 967], [480, 960, 480]),
  ('boundary control 5', [[480, 960], 500, 490], [495, 495, 0]),
  ('normal control 6', [[540, 1050], 539, 1049], [540, 1050, 510]),
  ('normal control 7', [[480, 720], 475, 719], [480, 720, 240]),
  ('normal control 8', [[480, 990], 488, 989], [495, 990, 495])],
 [('regression: quarter hour midpoint 1', [[480, 960], 488, 952], [495, 945, 450]),
  ('regression variant: quarter hour midpoint 2', [[540, 1020], 532, 1032], [525, 1035, 510]),
  ('partial repair guard 3', [[480, 720], 494, 742], [495, 735, 240]),
  ('boundary control 4', [[480, 960], 487, 953], [480, 960, 480]),
  ('normal control 5', [[420, 660], 427, 661], [420, 660, 240]),
  ('normal control 6', [[540, 780], 554, 789], [555, 795, 240]),
  ('normal control 7', [[540, 1050], 532, 1072], [525, 1065, 540]),
  ('normal control 8', [[420, 930], 410, 939], [405, 945, 540])],
 [('regression: quarter hour midpoint 1', [[487, 967], 485, 970], [480, 960, 480]),
  ('regression variant: quarter hour midpoint 2', [[487, 727], 496, 732], [495, 720, 225]),
  ('partial repair guard 3', [[487, 997], 490, 1006], [495, 1005, 510]),
  ('boundary control 4', [[480, 960], 473, 967], [480, 960, 480]),
  ('boundary control 5', [[480, 960], 500, 490], [495, 495, 0]),
  ('normal control 6', [[600, 1110], 603, 1118], [600, 1125, 525]),
  ('normal control 7', [[480, 990], 472, 998], [465, 1005, 540]),
  ('normal control 8', [[480, 990], 487, 991], [480, 990, 510])],
 [('regression: quarter hour midpoint 1', [[487, 967], 480, 979], [480, 975, 495]),
  ('regression variant: quarter hour midpoint 2', [[420, 930], 412, 939], [405, 945, 540]),
  ('partial repair guard 3', [[540, 1020], 532, 1029], [525, 1035, 510]),
  ('boundary control 4', [[480, 960], 488, 952], [495, 945, 450]),
  ('boundary control 5', [[480, 960], 487, 953], [480, 960, 480]),
  ('normal control 6', [[600, 1080], 592, 1081], [585, 1080, 495]),
  ('normal control 7', [[480, 720], 488, 486], [495, 480, 0]),
  ('normal control 8', [[420, 930], 427, 935], [420, 930, 510])]]
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: quarter hour midpoint 1[480, 975, 495][465, 975, 510]Failed
regression variant: quarter hour midpoint 2[495, 1005, 510][495, 990, 495]Failed
partial repair guard 3[555, 1020, 465][555, 1020, 465]Passed
boundary control 4[495, 960, 465][495, 945, 450]Failed
boundary control 5[495, 960, 465][480, 960, 480]Failed
normal control 6[615, 840, 225][600, 840, 240]Failed
normal control 7[495, 480, 0][495, 480, 0]Passed
normal control 8[495, 735, 240][495, 720, 225]Failed

SHA-256 / a97ea564763033c277eadf536dd83ec7c56dccf50e2eb2b046d2efe7c81ca295

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(sched, punch_in, punch_out):
    start, end = sched
    def q(t):
        r = t % 15
        return t - r if r <= 7 else t + 15
    i = start if 0 < start - punch_in <= 7 else punch_in
    o = end if 0 < punch_out - end <= 7 else punch_out
    i, o = q(i), q(o)
    return [i, o, max(o - i, 0)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: quarter hour midpoint 1', [[480, 960], 472, 968], [465, 975, 510]),
  ('regression variant: quarter hour midpoint 2', [[487, 997], 494, 998], [495, 990, 495]),
  ('partial repair guard 3', [[540, 1020], 548, 1025], [555, 1020, 465]),
  ('boundary control 4', [[480, 960], 488, 952], [495, 945, 450]),
  ('boundary control 5', [[480, 960], 487, 953], [480, 960, 480]),
  ('normal control 6', [[600, 840], 607, 840], [600, 840, 240]),
  ('normal control 7', [[480, 720], 488, 486], [495, 480, 0]),
  ('normal control 8', [[487, 727], 495, 734], [495, 720, 225])],
 [('regression: quarter hour midpoint 1', [[480, 960], 487, 953], [480, 960, 480]),
  ('regression variant: quarter hour midpoint 2', [[487, 727], 495, 732], [495, 720, 225]),
  ('partial repair guard 3', [[540, 1050], 554, 1072], [555, 1065, 510]),
  ('boundary control 4', [[480, 960], 473, 967], [480, 960, 480]),
  ('boundary control 5', [[480, 960], 500, 490], [495, 495, 0]),
  ('normal control 6', [[540, 1050], 539, 1049], [540, 1050, 510]),
  ('normal control 7', [[480, 720], 475, 719], [480, 720, 240]),
  ('normal control 8', [[480, 990], 488, 989], [495, 990, 495])],
 [('regression: quarter hour midpoint 1', [[480, 960], 488, 952], [495, 945, 450]),
  ('regression variant: quarter hour midpoint 2', [[540, 1020], 532, 1032], [525, 1035, 510]),
  ('partial repair guard 3', [[480, 720], 494, 742], [495, 735, 240]),
  ('boundary control 4', [[480, 960], 487, 953], [480, 960, 480]),
  ('normal control 5', [[420, 660], 427, 661], [420, 660, 240]),
  ('normal control 6', [[540, 780], 554, 789], [555, 795, 240]),
  ('normal control 7', [[540, 1050], 532, 1072], [525, 1065, 540]),
  ('normal control 8', [[420, 930], 410, 939], [405, 945, 540])],
 [('regression: quarter hour midpoint 1', [[487, 967], 485, 970], [480, 960, 480]),
  ('regression variant: quarter hour midpoint 2', [[487, 727], 496, 732], [495, 720, 225]),
  ('partial repair guard 3', [[487, 997], 490, 1006], [495, 1005, 510]),
  ('boundary control 4', [[480, 960], 473, 967], [480, 960, 480]),
  ('boundary control 5', [[480, 960], 500, 490], [495, 495, 0]),
  ('normal control 6', [[600, 1110], 603, 1118], [600, 1125, 525]),
  ('normal control 7', [[480, 990], 472, 998], [465, 1005, 540]),
  ('normal control 8', [[480, 990], 487, 991], [480, 990, 510])],
 [('regression: quarter hour midpoint 1', [[487, 967], 480, 979], [480, 975, 495]),
  ('regression variant: quarter hour midpoint 2', [[420, 930], 412, 939], [405, 945, 540]),
  ('partial repair guard 3', [[540, 1020], 532, 1029], [525, 1035, 510]),
  ('boundary control 4', [[480, 960], 488, 952], [495, 945, 450]),
  ('boundary control 5', [[480, 960], 487, 953], [480, 960, 480]),
  ('normal control 6', [[600, 1080], 592, 1081], [585, 1080, 495]),
  ('normal control 7', [[480, 720], 488, 486], [495, 480, 0]),
  ('normal control 8', [[420, 930], 427, 935], [420, 930, 510])]]
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: quarter hour midpoint 1[465, 983, 518][465, 975, 510]Failed
regression variant: quarter hour midpoint 2[509, 990, 481][495, 990, 495]Failed
partial repair guard 3[563, 1020, 457][555, 1020, 465]Failed
boundary control 4[503, 945, 442][495, 945, 450]Failed
boundary control 5[480, 968, 488][480, 960, 480]Failed
normal control 6[600, 840, 240][600, 840, 240]Passed
normal control 7[503, 480, 0][495, 480, 0]Failed
normal control 8[495, 720, 225][495, 720, 225]Passed

SHA-256 / 671c50882f1f4b061c552c55630918297130ece7cb17e37ac24ad095b779ecf2

3 / The verified repair

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

N = 1
observations = []
def solve(sched, punch_in, punch_out):
    start, end = sched
    def q(t):
        r = t % 15
        return t - r if r <= 7 else t + 15 - r
    i = start if 0 < start - punch_in <= 7 else punch_in
    o = end if 0 < punch_out - end <= 7 else punch_out
    i, o = q(i), q(o)
    return [i, o, max(o - i, 0)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: quarter hour midpoint 1', [[480, 960], 472, 968], [465, 975, 510]),
  ('regression variant: quarter hour midpoint 2', [[487, 997], 494, 998], [495, 990, 495]),
  ('partial repair guard 3', [[540, 1020], 548, 1025], [555, 1020, 465]),
  ('boundary control 4', [[480, 960], 488, 952], [495, 945, 450]),
  ('boundary control 5', [[480, 960], 487, 953], [480, 960, 480]),
  ('normal control 6', [[600, 840], 607, 840], [600, 840, 240]),
  ('normal control 7', [[480, 720], 488, 486], [495, 480, 0]),
  ('normal control 8', [[487, 727], 495, 734], [495, 720, 225])],
 [('regression: quarter hour midpoint 1', [[480, 960], 487, 953], [480, 960, 480]),
  ('regression variant: quarter hour midpoint 2', [[487, 727], 495, 732], [495, 720, 225]),
  ('partial repair guard 3', [[540, 1050], 554, 1072], [555, 1065, 510]),
  ('boundary control 4', [[480, 960], 473, 967], [480, 960, 480]),
  ('boundary control 5', [[480, 960], 500, 490], [495, 495, 0]),
  ('normal control 6', [[540, 1050], 539, 1049], [540, 1050, 510]),
  ('normal control 7', [[480, 720], 475, 719], [480, 720, 240]),
  ('normal control 8', [[480, 990], 488, 989], [495, 990, 495])],
 [('regression: quarter hour midpoint 1', [[480, 960], 488, 952], [495, 945, 450]),
  ('regression variant: quarter hour midpoint 2', [[540, 1020], 532, 1032], [525, 1035, 510]),
  ('partial repair guard 3', [[480, 720], 494, 742], [495, 735, 240]),
  ('boundary control 4', [[480, 960], 487, 953], [480, 960, 480]),
  ('normal control 5', [[420, 660], 427, 661], [420, 660, 240]),
  ('normal control 6', [[540, 780], 554, 789], [555, 795, 240]),
  ('normal control 7', [[540, 1050], 532, 1072], [525, 1065, 540]),
  ('normal control 8', [[420, 930], 410, 939], [405, 945, 540])],
 [('regression: quarter hour midpoint 1', [[487, 967], 485, 970], [480, 960, 480]),
  ('regression variant: quarter hour midpoint 2', [[487, 727], 496, 732], [495, 720, 225]),
  ('partial repair guard 3', [[487, 997], 490, 1006], [495, 1005, 510]),
  ('boundary control 4', [[480, 960], 473, 967], [480, 960, 480]),
  ('boundary control 5', [[480, 960], 500, 490], [495, 495, 0]),
  ('normal control 6', [[600, 1110], 603, 1118], [600, 1125, 525]),
  ('normal control 7', [[480, 990], 472, 998], [465, 1005, 540]),
  ('normal control 8', [[480, 990], 487, 991], [480, 990, 510])],
 [('regression: quarter hour midpoint 1', [[487, 967], 480, 979], [480, 975, 495]),
  ('regression variant: quarter hour midpoint 2', [[420, 930], 412, 939], [405, 945, 540]),
  ('partial repair guard 3', [[540, 1020], 532, 1029], [525, 1035, 510]),
  ('boundary control 4', [[480, 960], 488, 952], [495, 945, 450]),
  ('boundary control 5', [[480, 960], 487, 953], [480, 960, 480]),
  ('normal control 6', [[600, 1080], 592, 1081], [585, 1080, 495]),
  ('normal control 7', [[480, 720], 488, 486], [495, 480, 0]),
  ('normal control 8', [[420, 930], 427, 935], [420, 930, 510])]]
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: quarter hour midpoint 1[465, 975, 510][465, 975, 510]Passed
regression variant: quarter hour midpoint 2[495, 990, 495][495, 990, 495]Passed
partial repair guard 3[555, 1020, 465][555, 1020, 465]Passed
boundary control 4[495, 945, 450][495, 945, 450]Passed
boundary control 5[480, 960, 480][480, 960, 480]Passed
normal control 6[600, 840, 240][600, 840, 240]Passed
normal control 7[495, 480, 0][495, 480, 0]Passed
normal control 8[495, 720, 225][495, 720, 225]Passed

SHA-256 / 0bb0767840e288139d55d82f2e5a7378d94ce21e43125e0890cddfe273db5853

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

Case digest / 48aa0e4b97341e3fe60aa619afc091fc03609a622f320f9c67d57e4fcf323d09