FA-77041 / Calendar recurrence rules / Open access
Window query for recurring instances with duration: fast forward · case 01
A long instance already in progress when the window opens is missing from the result.
ROOT CAUSE
The skip-ahead index ignores instance duration and jumps past instances still running at window start.
VERIFIED REPAIR
At the fast forward decision use `max(0, (ws - dur - first) // step)`, leaving the other decision sites of the model unchanged.
Unsuccessful approach: The partial repair `max(0, (ws - first) // step - 1)` looks back a single step, which is insufficient when the duration exceeds the interval.
Case contract
Instances start at dtstart + k*interval_hours for k < count and last duration_min minutes. A window [window_start, window_end) returns every instance whose half-open span [s, s+duration) overlaps it; a zero-duration instance is returned when window_start <= s < window_end. The query may skip ahead but COUNT is always counted from dtstart. Return ISO start times (minutes).
Why this case matters
Recurring calendar series are expanded into concrete instances for display, reminders and conflict checks.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import datetime as dt
import calendar
N = 1
observations = []
def solve(dtstart, interval_hours, duration_min, count, window_start, window_end):
first = dt.datetime.fromisoformat(dtstart)
ws = dt.datetime.fromisoformat(window_start)
we = dt.datetime.fromisoformat(window_end)
dur = dt.timedelta(minutes=duration_min)
step = dt.timedelta(hours=interval_hours)
k0 = max(0, (ws - first) // step)
out = []
for k in range(k0, count):
s = first + k * step
if s >= we:
break
if (s + dur > ws) if duration_min else s >= ws:
out.append(s.isoformat(timespec='minutes'))
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: in-progress long meeting',
['2024-01-01T00:00', 1, 180, 20, '2024-01-01T10:30', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00']),
('touching end excluded',
['2024-01-01T08:00', 2, 60, 10, '2024-01-01T09:00', '2024-01-01T12:00'],
['2024-01-01T10:00']),
('window end exclusive',
['2024-01-01T08:00', 2, 30, 10, '2024-01-01T08:15', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T10:00']),
('zero duration instants',
['2024-01-01T00:00', 6, 0, 10, '2024-01-01T12:00', '2024-01-02T00:00'],
['2024-01-01T12:00', '2024-01-01T18:00']),
('late window beyond count',
['2024-01-01T00:00', 24, 60, 5, '2024-01-04T00:00', '2024-01-10T00:00'],
['2024-01-04T00:00', '2024-01-05T00:00']),
('window before dtstart',
['2024-01-05T09:00', 24, 90, 3, '2024-01-01T00:00', '2024-01-06T12:00'],
['2024-01-05T09:00', '2024-01-06T09:00']),
('duration longer than interval',
['2024-02-01T00:00', 2, 300, 12, '2024-02-01T09:00', '2024-02-01T10:00'],
['2024-02-01T06:00', '2024-02-01T08:00'])],
[('window end exclusive',
['2024-01-01T08:00', 2, 30, 10, '2024-01-01T08:15', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T10:00']),
('zero duration instants',
['2024-01-01T00:00', 6, 0, 10, '2024-01-01T12:00', '2024-01-02T00:00'],
['2024-01-01T12:00', '2024-01-01T18:00']),
('late window beyond count',
['2024-01-01T00:00', 24, 60, 5, '2024-01-04T00:00', '2024-01-10T00:00'],
['2024-01-04T00:00', '2024-01-05T00:00']),
('window before dtstart',
['2024-01-05T09:00', 24, 90, 3, '2024-01-01T00:00', '2024-01-06T12:00'],
['2024-01-05T09:00', '2024-01-06T09:00']),
('duration longer than interval',
['2024-02-01T00:00', 2, 300, 12, '2024-02-01T09:00', '2024-02-01T10:00'],
['2024-02-01T06:00', '2024-02-01T08:00']),
('window mid series',
['2024-03-01T06:00', 4, 120, 30, '2024-03-02T07:00', '2024-03-02T15:00'],
['2024-03-02T06:00', '2024-03-02T10:00', '2024-03-02T14:00']),
('instance ends at window start',
['2024-03-01T00:00', 3, 180, 8, '2024-03-01T06:00', '2024-03-01T07:00'],
['2024-03-01T06:00']),
('regression: in-progress long meeting',
['2024-01-01T00:00', 1, 180, 20, '2024-01-01T10:30', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00'])],
[('late window beyond count',
['2024-01-01T00:00', 24, 60, 5, '2024-01-04T00:00', '2024-01-10T00:00'],
['2024-01-04T00:00', '2024-01-05T00:00']),
('window before dtstart',
['2024-01-05T09:00', 24, 90, 3, '2024-01-01T00:00', '2024-01-06T12:00'],
['2024-01-05T09:00', '2024-01-06T09:00']),
('duration longer than interval',
['2024-02-01T00:00', 2, 300, 12, '2024-02-01T09:00', '2024-02-01T10:00'],
['2024-02-01T06:00', '2024-02-01T08:00']),
('window mid series',
['2024-03-01T06:00', 4, 120, 30, '2024-03-02T07:00', '2024-03-02T15:00'],
['2024-03-02T06:00', '2024-03-02T10:00', '2024-03-02T14:00']),
('instance ends at window start',
['2024-03-01T00:00', 3, 180, 8, '2024-03-01T06:00', '2024-03-01T07:00'],
['2024-03-01T06:00']),
('count exactly reaches window',
['2024-04-01T00:00', 12, 60, 4, '2024-04-02T11:30', '2024-04-03T00:00'],
['2024-04-02T12:00']),
('long instance from before window, short count',
['2024-05-01T00:00', 1, 600, 3, '2024-05-01T05:00', '2024-05-01T06:00'],
['2024-05-01T00:00', '2024-05-01T01:00', '2024-05-01T02:00'])],
[('duration longer than interval',
['2024-02-01T00:00', 2, 300, 12, '2024-02-01T09:00', '2024-02-01T10:00'],
['2024-02-01T06:00', '2024-02-01T08:00']),
('window mid series',
['2024-03-01T06:00', 4, 120, 30, '2024-03-02T07:00', '2024-03-02T15:00'],
['2024-03-02T06:00', '2024-03-02T10:00', '2024-03-02T14:00']),
('instance ends at window start',
['2024-03-01T00:00', 3, 180, 8, '2024-03-01T06:00', '2024-03-01T07:00'],
['2024-03-01T06:00']),
('count exactly reaches window',
['2024-04-01T00:00', 12, 60, 4, '2024-04-02T11:30', '2024-04-03T00:00'],
['2024-04-02T12:00']),
('long instance from before window, short count',
['2024-05-01T00:00', 1, 600, 3, '2024-05-01T05:00', '2024-05-01T06:00'],
['2024-05-01T00:00', '2024-05-01T01:00', '2024-05-01T02:00']),
('regression: in-progress long meeting',
['2024-01-01T00:00', 1, 180, 20, '2024-01-01T10:30', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00']),
('touching end excluded',
['2024-01-01T08:00', 2, 60, 10, '2024-01-01T09:00', '2024-01-01T12:00'],
['2024-01-01T10:00'])],
[('instance ends at window start',
['2024-03-01T00:00', 3, 180, 8, '2024-03-01T06:00', '2024-03-01T07:00'],
['2024-03-01T06:00']),
('count exactly reaches window',
['2024-04-01T00:00', 12, 60, 4, '2024-04-02T11:30', '2024-04-03T00:00'],
['2024-04-02T12:00']),
('long instance from before window, short count',
['2024-05-01T00:00', 1, 600, 3, '2024-05-01T05:00', '2024-05-01T06:00'],
['2024-05-01T00:00', '2024-05-01T01:00', '2024-05-01T02:00']),
('regression: in-progress long meeting',
['2024-01-01T00:00', 1, 180, 20, '2024-01-01T10:30', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00']),
('touching end excluded',
['2024-01-01T08:00', 2, 60, 10, '2024-01-01T09:00', '2024-01-01T12:00'],
['2024-01-01T10:00']),
('window end exclusive',
['2024-01-01T08:00', 2, 30, 10, '2024-01-01T08:15', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T10:00']),
('zero duration instants',
['2024-01-01T00:00', 6, 0, 10, '2024-01-01T12:00', '2024-01-02T00:00'],
['2024-01-01T12:00', '2024-01-01T18:00'])]]
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: in-progress long meeting | ['2024-01-01T10:00', '2024-01-01T11:00'] | ['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00'] | Failed |
| touching end excluded | ['2024-01-01T10:00'] | ['2024-01-01T10:00'] | Passed |
| window end exclusive | ['2024-01-01T08:00', '2024-01-01T10:00'] | ['2024-01-01T08:00', '2024-01-01T10:00'] | Passed |
| zero duration instants | ['2024-01-01T12:00', '2024-01-01T18:00'] | ['2024-01-01T12:00', '2024-01-01T18:00'] | Passed |
| late window beyond count | ['2024-01-04T00:00', '2024-01-05T00:00'] | ['2024-01-04T00:00', '2024-01-05T00:00'] | Passed |
| window before dtstart | ['2024-01-05T09:00', '2024-01-06T09:00'] | ['2024-01-05T09:00', '2024-01-06T09:00'] | Passed |
| duration longer than interval | ['2024-02-01T08:00'] | ['2024-02-01T06:00', '2024-02-01T08:00'] | Failed |
SHA-256 / 52d5ec35f4be716e6ff937d90bb83c0267cdf9349dbb8fc0c300706c8a33830f
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import datetime as dt
import calendar
N = 1
observations = []
def solve(dtstart, interval_hours, duration_min, count, window_start, window_end):
first = dt.datetime.fromisoformat(dtstart)
ws = dt.datetime.fromisoformat(window_start)
we = dt.datetime.fromisoformat(window_end)
dur = dt.timedelta(minutes=duration_min)
step = dt.timedelta(hours=interval_hours)
k0 = max(0, (ws - first) // step - 1)
out = []
for k in range(k0, count):
s = first + k * step
if s >= we:
break
if (s + dur > ws) if duration_min else s >= ws:
out.append(s.isoformat(timespec='minutes'))
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: in-progress long meeting',
['2024-01-01T00:00', 1, 180, 20, '2024-01-01T10:30', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00']),
('touching end excluded',
['2024-01-01T08:00', 2, 60, 10, '2024-01-01T09:00', '2024-01-01T12:00'],
['2024-01-01T10:00']),
('window end exclusive',
['2024-01-01T08:00', 2, 30, 10, '2024-01-01T08:15', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T10:00']),
('zero duration instants',
['2024-01-01T00:00', 6, 0, 10, '2024-01-01T12:00', '2024-01-02T00:00'],
['2024-01-01T12:00', '2024-01-01T18:00']),
('late window beyond count',
['2024-01-01T00:00', 24, 60, 5, '2024-01-04T00:00', '2024-01-10T00:00'],
['2024-01-04T00:00', '2024-01-05T00:00']),
('window before dtstart',
['2024-01-05T09:00', 24, 90, 3, '2024-01-01T00:00', '2024-01-06T12:00'],
['2024-01-05T09:00', '2024-01-06T09:00']),
('duration longer than interval',
['2024-02-01T00:00', 2, 300, 12, '2024-02-01T09:00', '2024-02-01T10:00'],
['2024-02-01T06:00', '2024-02-01T08:00'])],
[('window end exclusive',
['2024-01-01T08:00', 2, 30, 10, '2024-01-01T08:15', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T10:00']),
('zero duration instants',
['2024-01-01T00:00', 6, 0, 10, '2024-01-01T12:00', '2024-01-02T00:00'],
['2024-01-01T12:00', '2024-01-01T18:00']),
('late window beyond count',
['2024-01-01T00:00', 24, 60, 5, '2024-01-04T00:00', '2024-01-10T00:00'],
['2024-01-04T00:00', '2024-01-05T00:00']),
('window before dtstart',
['2024-01-05T09:00', 24, 90, 3, '2024-01-01T00:00', '2024-01-06T12:00'],
['2024-01-05T09:00', '2024-01-06T09:00']),
('duration longer than interval',
['2024-02-01T00:00', 2, 300, 12, '2024-02-01T09:00', '2024-02-01T10:00'],
['2024-02-01T06:00', '2024-02-01T08:00']),
('window mid series',
['2024-03-01T06:00', 4, 120, 30, '2024-03-02T07:00', '2024-03-02T15:00'],
['2024-03-02T06:00', '2024-03-02T10:00', '2024-03-02T14:00']),
('instance ends at window start',
['2024-03-01T00:00', 3, 180, 8, '2024-03-01T06:00', '2024-03-01T07:00'],
['2024-03-01T06:00']),
('regression: in-progress long meeting',
['2024-01-01T00:00', 1, 180, 20, '2024-01-01T10:30', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00'])],
[('late window beyond count',
['2024-01-01T00:00', 24, 60, 5, '2024-01-04T00:00', '2024-01-10T00:00'],
['2024-01-04T00:00', '2024-01-05T00:00']),
('window before dtstart',
['2024-01-05T09:00', 24, 90, 3, '2024-01-01T00:00', '2024-01-06T12:00'],
['2024-01-05T09:00', '2024-01-06T09:00']),
('duration longer than interval',
['2024-02-01T00:00', 2, 300, 12, '2024-02-01T09:00', '2024-02-01T10:00'],
['2024-02-01T06:00', '2024-02-01T08:00']),
('window mid series',
['2024-03-01T06:00', 4, 120, 30, '2024-03-02T07:00', '2024-03-02T15:00'],
['2024-03-02T06:00', '2024-03-02T10:00', '2024-03-02T14:00']),
('instance ends at window start',
['2024-03-01T00:00', 3, 180, 8, '2024-03-01T06:00', '2024-03-01T07:00'],
['2024-03-01T06:00']),
('count exactly reaches window',
['2024-04-01T00:00', 12, 60, 4, '2024-04-02T11:30', '2024-04-03T00:00'],
['2024-04-02T12:00']),
('long instance from before window, short count',
['2024-05-01T00:00', 1, 600, 3, '2024-05-01T05:00', '2024-05-01T06:00'],
['2024-05-01T00:00', '2024-05-01T01:00', '2024-05-01T02:00'])],
[('duration longer than interval',
['2024-02-01T00:00', 2, 300, 12, '2024-02-01T09:00', '2024-02-01T10:00'],
['2024-02-01T06:00', '2024-02-01T08:00']),
('window mid series',
['2024-03-01T06:00', 4, 120, 30, '2024-03-02T07:00', '2024-03-02T15:00'],
['2024-03-02T06:00', '2024-03-02T10:00', '2024-03-02T14:00']),
('instance ends at window start',
['2024-03-01T00:00', 3, 180, 8, '2024-03-01T06:00', '2024-03-01T07:00'],
['2024-03-01T06:00']),
('count exactly reaches window',
['2024-04-01T00:00', 12, 60, 4, '2024-04-02T11:30', '2024-04-03T00:00'],
['2024-04-02T12:00']),
('long instance from before window, short count',
['2024-05-01T00:00', 1, 600, 3, '2024-05-01T05:00', '2024-05-01T06:00'],
['2024-05-01T00:00', '2024-05-01T01:00', '2024-05-01T02:00']),
('regression: in-progress long meeting',
['2024-01-01T00:00', 1, 180, 20, '2024-01-01T10:30', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00']),
('touching end excluded',
['2024-01-01T08:00', 2, 60, 10, '2024-01-01T09:00', '2024-01-01T12:00'],
['2024-01-01T10:00'])],
[('instance ends at window start',
['2024-03-01T00:00', 3, 180, 8, '2024-03-01T06:00', '2024-03-01T07:00'],
['2024-03-01T06:00']),
('count exactly reaches window',
['2024-04-01T00:00', 12, 60, 4, '2024-04-02T11:30', '2024-04-03T00:00'],
['2024-04-02T12:00']),
('long instance from before window, short count',
['2024-05-01T00:00', 1, 600, 3, '2024-05-01T05:00', '2024-05-01T06:00'],
['2024-05-01T00:00', '2024-05-01T01:00', '2024-05-01T02:00']),
('regression: in-progress long meeting',
['2024-01-01T00:00', 1, 180, 20, '2024-01-01T10:30', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00']),
('touching end excluded',
['2024-01-01T08:00', 2, 60, 10, '2024-01-01T09:00', '2024-01-01T12:00'],
['2024-01-01T10:00']),
('window end exclusive',
['2024-01-01T08:00', 2, 30, 10, '2024-01-01T08:15', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T10:00']),
('zero duration instants',
['2024-01-01T00:00', 6, 0, 10, '2024-01-01T12:00', '2024-01-02T00:00'],
['2024-01-01T12:00', '2024-01-01T18:00'])]]
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: in-progress long meeting | ['2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00'] | ['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00'] | Failed |
| touching end excluded | ['2024-01-01T10:00'] | ['2024-01-01T10:00'] | Passed |
| window end exclusive | ['2024-01-01T08:00', '2024-01-01T10:00'] | ['2024-01-01T08:00', '2024-01-01T10:00'] | Passed |
| zero duration instants | ['2024-01-01T12:00', '2024-01-01T18:00'] | ['2024-01-01T12:00', '2024-01-01T18:00'] | Passed |
| late window beyond count | ['2024-01-04T00:00', '2024-01-05T00:00'] | ['2024-01-04T00:00', '2024-01-05T00:00'] | Passed |
| window before dtstart | ['2024-01-05T09:00', '2024-01-06T09:00'] | ['2024-01-05T09:00', '2024-01-06T09:00'] | Passed |
| duration longer than interval | ['2024-02-01T06:00', '2024-02-01T08:00'] | ['2024-02-01T06:00', '2024-02-01T08:00'] | Passed |
SHA-256 / a93f9b45c12d1aaed16c497fca72ab2fa88f3808c0a4c139f257239109a1800b
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import datetime as dt
import calendar
N = 1
observations = []
def solve(dtstart, interval_hours, duration_min, count, window_start, window_end):
first = dt.datetime.fromisoformat(dtstart)
ws = dt.datetime.fromisoformat(window_start)
we = dt.datetime.fromisoformat(window_end)
dur = dt.timedelta(minutes=duration_min)
step = dt.timedelta(hours=interval_hours)
k0 = max(0, (ws - dur - first) // step)
out = []
for k in range(k0, count):
s = first + k * step
if s >= we:
break
if (s + dur > ws) if duration_min else s >= ws:
out.append(s.isoformat(timespec='minutes'))
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: in-progress long meeting',
['2024-01-01T00:00', 1, 180, 20, '2024-01-01T10:30', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00']),
('touching end excluded',
['2024-01-01T08:00', 2, 60, 10, '2024-01-01T09:00', '2024-01-01T12:00'],
['2024-01-01T10:00']),
('window end exclusive',
['2024-01-01T08:00', 2, 30, 10, '2024-01-01T08:15', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T10:00']),
('zero duration instants',
['2024-01-01T00:00', 6, 0, 10, '2024-01-01T12:00', '2024-01-02T00:00'],
['2024-01-01T12:00', '2024-01-01T18:00']),
('late window beyond count',
['2024-01-01T00:00', 24, 60, 5, '2024-01-04T00:00', '2024-01-10T00:00'],
['2024-01-04T00:00', '2024-01-05T00:00']),
('window before dtstart',
['2024-01-05T09:00', 24, 90, 3, '2024-01-01T00:00', '2024-01-06T12:00'],
['2024-01-05T09:00', '2024-01-06T09:00']),
('duration longer than interval',
['2024-02-01T00:00', 2, 300, 12, '2024-02-01T09:00', '2024-02-01T10:00'],
['2024-02-01T06:00', '2024-02-01T08:00'])],
[('window end exclusive',
['2024-01-01T08:00', 2, 30, 10, '2024-01-01T08:15', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T10:00']),
('zero duration instants',
['2024-01-01T00:00', 6, 0, 10, '2024-01-01T12:00', '2024-01-02T00:00'],
['2024-01-01T12:00', '2024-01-01T18:00']),
('late window beyond count',
['2024-01-01T00:00', 24, 60, 5, '2024-01-04T00:00', '2024-01-10T00:00'],
['2024-01-04T00:00', '2024-01-05T00:00']),
('window before dtstart',
['2024-01-05T09:00', 24, 90, 3, '2024-01-01T00:00', '2024-01-06T12:00'],
['2024-01-05T09:00', '2024-01-06T09:00']),
('duration longer than interval',
['2024-02-01T00:00', 2, 300, 12, '2024-02-01T09:00', '2024-02-01T10:00'],
['2024-02-01T06:00', '2024-02-01T08:00']),
('window mid series',
['2024-03-01T06:00', 4, 120, 30, '2024-03-02T07:00', '2024-03-02T15:00'],
['2024-03-02T06:00', '2024-03-02T10:00', '2024-03-02T14:00']),
('instance ends at window start',
['2024-03-01T00:00', 3, 180, 8, '2024-03-01T06:00', '2024-03-01T07:00'],
['2024-03-01T06:00']),
('regression: in-progress long meeting',
['2024-01-01T00:00', 1, 180, 20, '2024-01-01T10:30', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00'])],
[('late window beyond count',
['2024-01-01T00:00', 24, 60, 5, '2024-01-04T00:00', '2024-01-10T00:00'],
['2024-01-04T00:00', '2024-01-05T00:00']),
('window before dtstart',
['2024-01-05T09:00', 24, 90, 3, '2024-01-01T00:00', '2024-01-06T12:00'],
['2024-01-05T09:00', '2024-01-06T09:00']),
('duration longer than interval',
['2024-02-01T00:00', 2, 300, 12, '2024-02-01T09:00', '2024-02-01T10:00'],
['2024-02-01T06:00', '2024-02-01T08:00']),
('window mid series',
['2024-03-01T06:00', 4, 120, 30, '2024-03-02T07:00', '2024-03-02T15:00'],
['2024-03-02T06:00', '2024-03-02T10:00', '2024-03-02T14:00']),
('instance ends at window start',
['2024-03-01T00:00', 3, 180, 8, '2024-03-01T06:00', '2024-03-01T07:00'],
['2024-03-01T06:00']),
('count exactly reaches window',
['2024-04-01T00:00', 12, 60, 4, '2024-04-02T11:30', '2024-04-03T00:00'],
['2024-04-02T12:00']),
('long instance from before window, short count',
['2024-05-01T00:00', 1, 600, 3, '2024-05-01T05:00', '2024-05-01T06:00'],
['2024-05-01T00:00', '2024-05-01T01:00', '2024-05-01T02:00'])],
[('duration longer than interval',
['2024-02-01T00:00', 2, 300, 12, '2024-02-01T09:00', '2024-02-01T10:00'],
['2024-02-01T06:00', '2024-02-01T08:00']),
('window mid series',
['2024-03-01T06:00', 4, 120, 30, '2024-03-02T07:00', '2024-03-02T15:00'],
['2024-03-02T06:00', '2024-03-02T10:00', '2024-03-02T14:00']),
('instance ends at window start',
['2024-03-01T00:00', 3, 180, 8, '2024-03-01T06:00', '2024-03-01T07:00'],
['2024-03-01T06:00']),
('count exactly reaches window',
['2024-04-01T00:00', 12, 60, 4, '2024-04-02T11:30', '2024-04-03T00:00'],
['2024-04-02T12:00']),
('long instance from before window, short count',
['2024-05-01T00:00', 1, 600, 3, '2024-05-01T05:00', '2024-05-01T06:00'],
['2024-05-01T00:00', '2024-05-01T01:00', '2024-05-01T02:00']),
('regression: in-progress long meeting',
['2024-01-01T00:00', 1, 180, 20, '2024-01-01T10:30', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00']),
('touching end excluded',
['2024-01-01T08:00', 2, 60, 10, '2024-01-01T09:00', '2024-01-01T12:00'],
['2024-01-01T10:00'])],
[('instance ends at window start',
['2024-03-01T00:00', 3, 180, 8, '2024-03-01T06:00', '2024-03-01T07:00'],
['2024-03-01T06:00']),
('count exactly reaches window',
['2024-04-01T00:00', 12, 60, 4, '2024-04-02T11:30', '2024-04-03T00:00'],
['2024-04-02T12:00']),
('long instance from before window, short count',
['2024-05-01T00:00', 1, 600, 3, '2024-05-01T05:00', '2024-05-01T06:00'],
['2024-05-01T00:00', '2024-05-01T01:00', '2024-05-01T02:00']),
('regression: in-progress long meeting',
['2024-01-01T00:00', 1, 180, 20, '2024-01-01T10:30', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00']),
('touching end excluded',
['2024-01-01T08:00', 2, 60, 10, '2024-01-01T09:00', '2024-01-01T12:00'],
['2024-01-01T10:00']),
('window end exclusive',
['2024-01-01T08:00', 2, 30, 10, '2024-01-01T08:15', '2024-01-01T12:00'],
['2024-01-01T08:00', '2024-01-01T10:00']),
('zero duration instants',
['2024-01-01T00:00', 6, 0, 10, '2024-01-01T12:00', '2024-01-02T00:00'],
['2024-01-01T12:00', '2024-01-01T18:00'])]]
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: in-progress long meeting | ['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00'] | ['2024-01-01T08:00', '2024-01-01T09:00', '2024-01-01T10:00', '2024-01-01T11:00'] | Passed |
| touching end excluded | ['2024-01-01T10:00'] | ['2024-01-01T10:00'] | Passed |
| window end exclusive | ['2024-01-01T08:00', '2024-01-01T10:00'] | ['2024-01-01T08:00', '2024-01-01T10:00'] | Passed |
| zero duration instants | ['2024-01-01T12:00', '2024-01-01T18:00'] | ['2024-01-01T12:00', '2024-01-01T18:00'] | Passed |
| late window beyond count | ['2024-01-04T00:00', '2024-01-05T00:00'] | ['2024-01-04T00:00', '2024-01-05T00:00'] | Passed |
| window before dtstart | ['2024-01-05T09:00', '2024-01-06T09:00'] | ['2024-01-05T09:00', '2024-01-06T09:00'] | Passed |
| duration longer than interval | ['2024-02-01T06:00', '2024-02-01T08:00'] | ['2024-02-01T06:00', '2024-02-01T08:00'] | Passed |
SHA-256 / f9862467c31d40ce11886490907a570e66c19fac5d1d321b37e9849573f78fc8
Verification & scope
Stipulated, bounded recurrence-expansion model evaluated offline on explicit fixtures; it is not a complete iCalendar implementation and makes no claim of standards conformance. 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:49:21.888981+00:00.
Case digest / f85c9536daf8db6db16c54270fa9bc417a63f5609067bd2dda9374e191c69a2e