FAILURE MAP
← Case archive

FA-93146 / EV charging session scheduling / Open access

Weekly recurring charging windows: overnight head start · case 01

The opening minute of an overnight window is refused.

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

ROOT CAUSE

The overnight head uses a strict comparison with the start minute.

VERIFIED REPAIR

Allow minutes >= start on the start day.

Unsuccessful approach: Excluding 23:59 cuts the last minute before midnight.

Case contract

rules are [day_mask, start, end] with bit 0 = Monday .. bit 6 = Sunday. start < end is a same-day window [start, end); start == end means the whole selected day; start > end crosses midnight and belongs to its start day (Sunday continues into Monday). Return the sorted indices of rules allowing charging at (day 0..6, minute 0..1439).

Why this case matters

Depot, workplace and public EV chargers schedule sessions against prices, circuit limits and departure deadlines; a wrong decision silently strands a driver or overloads a feeder.

1 / The failure

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

N = 1
observations = []
def solve(rules, day, minute):
    hits = []
    for i, (mask, s, e) in enumerate(rules):
        today = mask >> day & 1
        yday = mask >> (day - 1) % 7 & 1
        if s == e:
            if today:
                hits.append(i)
        elif s < e:
            if today and s <= minute < e:
                hits.append(i)
        elif (today and minute > s) or (yday and minute < e):
            hits.append(i)
    return hits
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start', [[[96, 60, 1380], [57, 1080, 60], [60, 0, 1320]], 4, 1080],
   [1, 2]],
  ['regression: overnight head start (partial repair)',
   [[[80, 1380, 60], [124, 1380, 1320], [58, 1080, 420]], 4, 1439], [0, 1, 2]],
  ['control 1', [[[75, 1380, 360]], 0, 1379], []],
  ['control 2', [[[26, 1380, 420], [118, 360, 0], [104, 1080, 1080]], 3, 0], [2]]],
 [['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start', [[[63, 360, 360], [35, 60, 0], [120, 1080, 420]], 5, 1080],
   [0, 1, 2]],
  ['regression: overnight head start (partial repair)',
   [[[113, 1320, 0], [95, 0, 0], [95, 1320, 0], [124, 1380, 60]], 0, 1439], [0, 1, 2]],
  ['control 1', [[[18, 60, 0], [118, 1080, 0], [124, 60, 360], [93, 1080, 60]], 4, 0], [3]],
  ['control 2', [[[28, 1320, 1080], [123, 420, 1380], [9, 1380, 0]], 6, 359], []]],
 [['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start', [[[59, 360, 60], [45, 420, 60]], 5, 360], [0]],
  ['regression: overnight head start (partial repair)',
   [[[58, 0, 1080], [124, 1320, 1080], [79, 0, 0], [46, 1380, 60]], 1, 1439], [2, 3]],
  ['control 1', [[[103, 0, 360], [65, 360, 1380], [37, 1080, 1080]], 4, 60], []],
  ['control 2', [[[52, 420, 1320], [97, 1080, 360]], 0, 0], [1]]],
 [['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start',
   [[[92, 360, 60], [95, 420, 1080], [89, 0, 360], [2, 360, 420]], 6, 360], [0]],
  ['regression: overnight head start (partial repair)',
   [[[69, 0, 420], [105, 420, 1380], [94, 360, 0]], 3, 1439], [2]],
  ['control 1', [[[105, 420, 360], [31, 1380, 1320], [47, 1080, 1320]], 4, 60], [0, 1]],
  ['control 2', [[[59, 360, 60], [45, 420, 60]], 5, 360], [0]]],
 [['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start',
   [[[20, 420, 1080], [44, 1320, 60], [78, 1080, 360]], 1, 1080], [2]],
  ['regression: overnight head start (partial repair)',
   [[[69, 0, 420], [105, 420, 1380], [94, 360, 0]], 3, 1439], [2]],
  ['control 1', [[[51, 360, 60], [78, 1080, 1080], [25, 1320, 360], [11, 360, 0]], 2, 1380], [1]],
  ['control 2', [[[16, 1380, 0]], 1, 360], []]]]
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
boundary: Monday morning after Sunday night window[0][0]Passed
boundary: same-day window end minute[][]Passed
boundary: whole-day rule[0][0]Passed
regression: overnight head start[2][1, 2]Failed
regression: overnight head start (partial repair)[0, 1, 2][0, 1, 2]Passed
control 1[][]Passed
control 2[2][2]Passed

SHA-256 / 16cd064173525151aed393989db8dad7e76676876de5427e5985cc1c61829156

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(rules, day, minute):
    hits = []
    for i, (mask, s, e) in enumerate(rules):
        today = mask >> day & 1
        yday = mask >> (day - 1) % 7 & 1
        if s == e:
            if today:
                hits.append(i)
        elif s < e:
            if today and s <= minute < e:
                hits.append(i)
        elif (today and minute >= s and minute < 1439) or (yday and minute < e):
            hits.append(i)
    return hits
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start', [[[96, 60, 1380], [57, 1080, 60], [60, 0, 1320]], 4, 1080],
   [1, 2]],
  ['regression: overnight head start (partial repair)',
   [[[80, 1380, 60], [124, 1380, 1320], [58, 1080, 420]], 4, 1439], [0, 1, 2]],
  ['control 1', [[[75, 1380, 360]], 0, 1379], []],
  ['control 2', [[[26, 1380, 420], [118, 360, 0], [104, 1080, 1080]], 3, 0], [2]]],
 [['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start', [[[63, 360, 360], [35, 60, 0], [120, 1080, 420]], 5, 1080],
   [0, 1, 2]],
  ['regression: overnight head start (partial repair)',
   [[[113, 1320, 0], [95, 0, 0], [95, 1320, 0], [124, 1380, 60]], 0, 1439], [0, 1, 2]],
  ['control 1', [[[18, 60, 0], [118, 1080, 0], [124, 60, 360], [93, 1080, 60]], 4, 0], [3]],
  ['control 2', [[[28, 1320, 1080], [123, 420, 1380], [9, 1380, 0]], 6, 359], []]],
 [['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start', [[[59, 360, 60], [45, 420, 60]], 5, 360], [0]],
  ['regression: overnight head start (partial repair)',
   [[[58, 0, 1080], [124, 1320, 1080], [79, 0, 0], [46, 1380, 60]], 1, 1439], [2, 3]],
  ['control 1', [[[103, 0, 360], [65, 360, 1380], [37, 1080, 1080]], 4, 60], []],
  ['control 2', [[[52, 420, 1320], [97, 1080, 360]], 0, 0], [1]]],
 [['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start',
   [[[92, 360, 60], [95, 420, 1080], [89, 0, 360], [2, 360, 420]], 6, 360], [0]],
  ['regression: overnight head start (partial repair)',
   [[[69, 0, 420], [105, 420, 1380], [94, 360, 0]], 3, 1439], [2]],
  ['control 1', [[[105, 420, 360], [31, 1380, 1320], [47, 1080, 1320]], 4, 60], [0, 1]],
  ['control 2', [[[59, 360, 60], [45, 420, 60]], 5, 360], [0]]],
 [['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start',
   [[[20, 420, 1080], [44, 1320, 60], [78, 1080, 360]], 1, 1080], [2]],
  ['regression: overnight head start (partial repair)',
   [[[69, 0, 420], [105, 420, 1380], [94, 360, 0]], 3, 1439], [2]],
  ['control 1', [[[51, 360, 60], [78, 1080, 1080], [25, 1320, 360], [11, 360, 0]], 2, 1380], [1]],
  ['control 2', [[[16, 1380, 0]], 1, 360], []]]]
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
boundary: Monday morning after Sunday night window[0][0]Passed
boundary: same-day window end minute[][]Passed
boundary: whole-day rule[0][0]Passed
regression: overnight head start[1, 2][1, 2]Passed
regression: overnight head start (partial repair)[][0, 1, 2]Failed
control 1[][]Passed
control 2[2][2]Passed

SHA-256 / 047551fda5b6fe9ff6a9265411e99e9173502b29594b11d10d6ada1d6c57d315

3 / The verified repair

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

N = 1
observations = []
def solve(rules, day, minute):
    hits = []
    for i, (mask, s, e) in enumerate(rules):
        today = mask >> day & 1
        yday = mask >> (day - 1) % 7 & 1
        if s == e:
            if today:
                hits.append(i)
        elif s < e:
            if today and s <= minute < e:
                hits.append(i)
        elif (today and minute >= s) or (yday and minute < e):
            hits.append(i)
    return hits
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start', [[[96, 60, 1380], [57, 1080, 60], [60, 0, 1320]], 4, 1080],
   [1, 2]],
  ['regression: overnight head start (partial repair)',
   [[[80, 1380, 60], [124, 1380, 1320], [58, 1080, 420]], 4, 1439], [0, 1, 2]],
  ['control 1', [[[75, 1380, 360]], 0, 1379], []],
  ['control 2', [[[26, 1380, 420], [118, 360, 0], [104, 1080, 1080]], 3, 0], [2]]],
 [['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start', [[[63, 360, 360], [35, 60, 0], [120, 1080, 420]], 5, 1080],
   [0, 1, 2]],
  ['regression: overnight head start (partial repair)',
   [[[113, 1320, 0], [95, 0, 0], [95, 1320, 0], [124, 1380, 60]], 0, 1439], [0, 1, 2]],
  ['control 1', [[[18, 60, 0], [118, 1080, 0], [124, 60, 360], [93, 1080, 60]], 4, 0], [3]],
  ['control 2', [[[28, 1320, 1080], [123, 420, 1380], [9, 1380, 0]], 6, 359], []]],
 [['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start', [[[59, 360, 60], [45, 420, 60]], 5, 360], [0]],
  ['regression: overnight head start (partial repair)',
   [[[58, 0, 1080], [124, 1320, 1080], [79, 0, 0], [46, 1380, 60]], 1, 1439], [2, 3]],
  ['control 1', [[[103, 0, 360], [65, 360, 1380], [37, 1080, 1080]], 4, 60], []],
  ['control 2', [[[52, 420, 1320], [97, 1080, 360]], 0, 0], [1]]],
 [['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start',
   [[[92, 360, 60], [95, 420, 1080], [89, 0, 360], [2, 360, 420]], 6, 360], [0]],
  ['regression: overnight head start (partial repair)',
   [[[69, 0, 420], [105, 420, 1380], [94, 360, 0]], 3, 1439], [2]],
  ['control 1', [[[105, 420, 360], [31, 1380, 1320], [47, 1080, 1320]], 4, 60], [0, 1]],
  ['control 2', [[[59, 360, 60], [45, 420, 60]], 5, 360], [0]]],
 [['boundary: Monday morning after Sunday night window', [[[64, 1320, 360]], 0, 100], [0]],
  ['boundary: same-day window end minute', [[[127, 60, 360]], 3, 360], []],
  ['boundary: whole-day rule', [[[4, 420, 420]], 2, 5], [0]],
  ['regression: overnight head start',
   [[[20, 420, 1080], [44, 1320, 60], [78, 1080, 360]], 1, 1080], [2]],
  ['regression: overnight head start (partial repair)',
   [[[69, 0, 420], [105, 420, 1380], [94, 360, 0]], 3, 1439], [2]],
  ['control 1', [[[51, 360, 60], [78, 1080, 1080], [25, 1320, 360], [11, 360, 0]], 2, 1380], [1]],
  ['control 2', [[[16, 1380, 0]], 1, 360], []]]]
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
boundary: Monday morning after Sunday night window[0][0]Passed
boundary: same-day window end minute[][]Passed
boundary: whole-day rule[0][0]Passed
regression: overnight head start[1, 2][1, 2]Passed
regression: overnight head start (partial repair)[0, 1, 2][0, 1, 2]Passed
control 1[][]Passed
control 2[2][2]Passed

SHA-256 / bfbc13306be60d26a6ef0d241f1248f6f86f4c14c5e0ff37f612130fe3283d79

Verification & scope

Deterministic stipulated toy contract for teaching; no claim of conformance with any standard, vendor protocol or production controller. 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:51:52.424193+00:00.

Case digest / 4fb628f513fe821e811fffd0ed7b3f3f35c1d2c53b34adb5e6e827c9dac44e51