FA-76981 / Calendar recurrence rules / Open access
Merging RRULE instances with RDATE and EXDATE: exdate scope · case 01
An EXDATE matching an RDATE leaves the RDATE on the calendar.
ROOT CAUSE
EXDATE is applied to the rule instances only.
VERIFIED REPAIR
At the exdate scope decision use `[d for d in rule + extra if d not in excluded]`, leaving the other decision sites of the model unchanged.
Unsuccessful approach: The partial repair `[d for d in rule if d not in excluded] + [d for d in extra if d not in rule]` avoids RDATE duplicates of rule dates but still does not exclude RDATEs.
Case contract
All-day series: the rule yields exactly count instances dtstart + k*interval days (COUNT counts rule instances before exclusions; RDATEs never consume COUNT). The instance set is rule plus RDATE minus EXDATE; EXDATE also removes RDATEs. EXDATE values may carry a time part (YYYY-MM-DDTHH:MM:SS) and then exclude their calendar date. Return the unique dates sorted ascending.
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, count, rdates, exdates):
start = dt.date.fromisoformat(dtstart)
excluded = {dt.date.fromisoformat(x[:10]) for x in exdates}
rule = [start + dt.timedelta(days=k * interval) for k in range(count)]
extra = [dt.date.fromisoformat(x) for x in rdates]
rule = rule
merged = [d for d in rule if d not in excluded] + extra
result = sorted(set(merged))
return [d.isoformat() for d in result]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: exdate does not extend count',
['2024-03-01', 1, 5, [], ['2024-03-03']],
['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05']),
('timed exdate',
['2024-03-01', 2, 4, [], ['2024-03-05T09:30:00']],
['2024-03-01', '2024-03-03', '2024-03-07']),
('midnight exdate', ['2024-03-01', 1, 3, [], ['2024-03-02T00:00:00']], ['2024-03-01', '2024-03-03']),
('rdate equal to rule date',
['2024-01-01', 7, 3, ['2024-01-08'], []],
['2024-01-01', '2024-01-08', '2024-01-15']),
('rdate before dtstart',
['2024-01-10', 1, 3, ['2024-01-02'], []],
['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03']),
('exdate outside rule',
['2024-01-01', 3, 3, [], ['2024-01-02']],
['2024-01-01', '2024-01-04', '2024-01-07'])],
[('midnight exdate', ['2024-03-01', 1, 3, [], ['2024-03-02T00:00:00']], ['2024-03-01', '2024-03-03']),
('rdate equal to rule date',
['2024-01-01', 7, 3, ['2024-01-08'], []],
['2024-01-01', '2024-01-08', '2024-01-15']),
('rdate before dtstart',
['2024-01-10', 1, 3, ['2024-01-02'], []],
['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03']),
('exdate outside rule',
['2024-01-01', 3, 3, [], ['2024-01-02']],
['2024-01-01', '2024-01-04', '2024-01-07']),
('rdate between instances',
['2024-05-01', 10, 3, ['2024-05-05', '2024-05-30'], ['2024-05-11']],
['2024-05-01', '2024-05-05', '2024-05-21', '2024-05-30']),
('count zero with rdate', ['2024-01-01', 1, 0, ['2024-01-03'], []], ['2024-01-03'])],
[('rdate before dtstart',
['2024-01-10', 1, 3, ['2024-01-02'], []],
['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03']),
('exdate outside rule',
['2024-01-01', 3, 3, [], ['2024-01-02']],
['2024-01-01', '2024-01-04', '2024-01-07']),
('rdate between instances',
['2024-05-01', 10, 3, ['2024-05-05', '2024-05-30'], ['2024-05-11']],
['2024-05-01', '2024-05-05', '2024-05-21', '2024-05-30']),
('count zero with rdate', ['2024-01-01', 1, 0, ['2024-01-03'], []], ['2024-01-03']),
('duplicate rdates and timed exdate',
['2024-02-27', 1, 4, ['2024-03-05', '2024-03-05'], ['2024-02-28T12:00:00']],
['2024-02-27', '2024-02-29', '2024-03-01', '2024-03-05']),
('all excluded', ['2024-07-01', 1, 2, [], ['2024-07-01', '2024-07-02']], [])],
[('exdate outside rule',
['2024-01-01', 3, 3, [], ['2024-01-02']],
['2024-01-01', '2024-01-04', '2024-01-07']),
('rdate between instances',
['2024-05-01', 10, 3, ['2024-05-05', '2024-05-30'], ['2024-05-11']],
['2024-05-01', '2024-05-05', '2024-05-21', '2024-05-30']),
('count zero with rdate', ['2024-01-01', 1, 0, ['2024-01-03'], []], ['2024-01-03']),
('duplicate rdates and timed exdate',
['2024-02-27', 1, 4, ['2024-03-05', '2024-03-05'], ['2024-02-28T12:00:00']],
['2024-02-27', '2024-02-29', '2024-03-01', '2024-03-05']),
('all excluded', ['2024-07-01', 1, 2, [], ['2024-07-01', '2024-07-02']], []),
('regression: exdate does not extend count',
['2024-03-01', 1, 5, [], ['2024-03-03']],
['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05']),
('timed exdate',
['2024-03-01', 2, 4, [], ['2024-03-05T09:30:00']],
['2024-03-01', '2024-03-03', '2024-03-07']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03'])],
[('count zero with rdate', ['2024-01-01', 1, 0, ['2024-01-03'], []], ['2024-01-03']),
('duplicate rdates and timed exdate',
['2024-02-27', 1, 4, ['2024-03-05', '2024-03-05'], ['2024-02-28T12:00:00']],
['2024-02-27', '2024-02-29', '2024-03-01', '2024-03-05']),
('all excluded', ['2024-07-01', 1, 2, [], ['2024-07-01', '2024-07-02']], []),
('regression: exdate does not extend count',
['2024-03-01', 1, 5, [], ['2024-03-03']],
['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05']),
('timed exdate',
['2024-03-01', 2, 4, [], ['2024-03-05T09:30:00']],
['2024-03-01', '2024-03-03', '2024-03-07']),
('midnight exdate', ['2024-03-01', 1, 3, [], ['2024-03-02T00:00:00']], ['2024-03-01', '2024-03-03']),
('rdate equal to rule date',
['2024-01-01', 7, 3, ['2024-01-08'], []],
['2024-01-01', '2024-01-08', '2024-01-15']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03'])]]
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: exdate does not extend count | ['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05'] | ['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05'] | Passed |
| timed exdate | ['2024-03-01', '2024-03-03', '2024-03-07'] | ['2024-03-01', '2024-03-03', '2024-03-07'] | Passed |
| midnight exdate | ['2024-03-01', '2024-03-03'] | ['2024-03-01', '2024-03-03'] | Passed |
| rdate equal to rule date | ['2024-01-01', '2024-01-08', '2024-01-15'] | ['2024-01-01', '2024-01-08', '2024-01-15'] | Passed |
| rdate before dtstart | ['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12'] | ['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12'] | Passed |
| exdate removes rdate | ['2024-01-01', '2024-01-02', '2024-01-03', '2024-02-01'] | ['2024-01-01', '2024-01-02', '2024-01-03'] | Failed |
| exdate outside rule | ['2024-01-01', '2024-01-04', '2024-01-07'] | ['2024-01-01', '2024-01-04', '2024-01-07'] | Passed |
SHA-256 / 203b9e66b748b79f5491912a4d62c7be3d1fe6ffedfabaea08f37ac153326c81
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, count, rdates, exdates):
start = dt.date.fromisoformat(dtstart)
excluded = {dt.date.fromisoformat(x[:10]) for x in exdates}
rule = [start + dt.timedelta(days=k * interval) for k in range(count)]
extra = [dt.date.fromisoformat(x) for x in rdates]
rule = rule
merged = [d for d in rule if d not in excluded] + [d for d in extra if d not in rule]
result = sorted(set(merged))
return [d.isoformat() for d in result]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: exdate does not extend count',
['2024-03-01', 1, 5, [], ['2024-03-03']],
['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05']),
('timed exdate',
['2024-03-01', 2, 4, [], ['2024-03-05T09:30:00']],
['2024-03-01', '2024-03-03', '2024-03-07']),
('midnight exdate', ['2024-03-01', 1, 3, [], ['2024-03-02T00:00:00']], ['2024-03-01', '2024-03-03']),
('rdate equal to rule date',
['2024-01-01', 7, 3, ['2024-01-08'], []],
['2024-01-01', '2024-01-08', '2024-01-15']),
('rdate before dtstart',
['2024-01-10', 1, 3, ['2024-01-02'], []],
['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03']),
('exdate outside rule',
['2024-01-01', 3, 3, [], ['2024-01-02']],
['2024-01-01', '2024-01-04', '2024-01-07'])],
[('midnight exdate', ['2024-03-01', 1, 3, [], ['2024-03-02T00:00:00']], ['2024-03-01', '2024-03-03']),
('rdate equal to rule date',
['2024-01-01', 7, 3, ['2024-01-08'], []],
['2024-01-01', '2024-01-08', '2024-01-15']),
('rdate before dtstart',
['2024-01-10', 1, 3, ['2024-01-02'], []],
['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03']),
('exdate outside rule',
['2024-01-01', 3, 3, [], ['2024-01-02']],
['2024-01-01', '2024-01-04', '2024-01-07']),
('rdate between instances',
['2024-05-01', 10, 3, ['2024-05-05', '2024-05-30'], ['2024-05-11']],
['2024-05-01', '2024-05-05', '2024-05-21', '2024-05-30']),
('count zero with rdate', ['2024-01-01', 1, 0, ['2024-01-03'], []], ['2024-01-03'])],
[('rdate before dtstart',
['2024-01-10', 1, 3, ['2024-01-02'], []],
['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03']),
('exdate outside rule',
['2024-01-01', 3, 3, [], ['2024-01-02']],
['2024-01-01', '2024-01-04', '2024-01-07']),
('rdate between instances',
['2024-05-01', 10, 3, ['2024-05-05', '2024-05-30'], ['2024-05-11']],
['2024-05-01', '2024-05-05', '2024-05-21', '2024-05-30']),
('count zero with rdate', ['2024-01-01', 1, 0, ['2024-01-03'], []], ['2024-01-03']),
('duplicate rdates and timed exdate',
['2024-02-27', 1, 4, ['2024-03-05', '2024-03-05'], ['2024-02-28T12:00:00']],
['2024-02-27', '2024-02-29', '2024-03-01', '2024-03-05']),
('all excluded', ['2024-07-01', 1, 2, [], ['2024-07-01', '2024-07-02']], [])],
[('exdate outside rule',
['2024-01-01', 3, 3, [], ['2024-01-02']],
['2024-01-01', '2024-01-04', '2024-01-07']),
('rdate between instances',
['2024-05-01', 10, 3, ['2024-05-05', '2024-05-30'], ['2024-05-11']],
['2024-05-01', '2024-05-05', '2024-05-21', '2024-05-30']),
('count zero with rdate', ['2024-01-01', 1, 0, ['2024-01-03'], []], ['2024-01-03']),
('duplicate rdates and timed exdate',
['2024-02-27', 1, 4, ['2024-03-05', '2024-03-05'], ['2024-02-28T12:00:00']],
['2024-02-27', '2024-02-29', '2024-03-01', '2024-03-05']),
('all excluded', ['2024-07-01', 1, 2, [], ['2024-07-01', '2024-07-02']], []),
('regression: exdate does not extend count',
['2024-03-01', 1, 5, [], ['2024-03-03']],
['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05']),
('timed exdate',
['2024-03-01', 2, 4, [], ['2024-03-05T09:30:00']],
['2024-03-01', '2024-03-03', '2024-03-07']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03'])],
[('count zero with rdate', ['2024-01-01', 1, 0, ['2024-01-03'], []], ['2024-01-03']),
('duplicate rdates and timed exdate',
['2024-02-27', 1, 4, ['2024-03-05', '2024-03-05'], ['2024-02-28T12:00:00']],
['2024-02-27', '2024-02-29', '2024-03-01', '2024-03-05']),
('all excluded', ['2024-07-01', 1, 2, [], ['2024-07-01', '2024-07-02']], []),
('regression: exdate does not extend count',
['2024-03-01', 1, 5, [], ['2024-03-03']],
['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05']),
('timed exdate',
['2024-03-01', 2, 4, [], ['2024-03-05T09:30:00']],
['2024-03-01', '2024-03-03', '2024-03-07']),
('midnight exdate', ['2024-03-01', 1, 3, [], ['2024-03-02T00:00:00']], ['2024-03-01', '2024-03-03']),
('rdate equal to rule date',
['2024-01-01', 7, 3, ['2024-01-08'], []],
['2024-01-01', '2024-01-08', '2024-01-15']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03'])]]
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: exdate does not extend count | ['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05'] | ['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05'] | Passed |
| timed exdate | ['2024-03-01', '2024-03-03', '2024-03-07'] | ['2024-03-01', '2024-03-03', '2024-03-07'] | Passed |
| midnight exdate | ['2024-03-01', '2024-03-03'] | ['2024-03-01', '2024-03-03'] | Passed |
| rdate equal to rule date | ['2024-01-01', '2024-01-08', '2024-01-15'] | ['2024-01-01', '2024-01-08', '2024-01-15'] | Passed |
| rdate before dtstart | ['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12'] | ['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12'] | Passed |
| exdate removes rdate | ['2024-01-01', '2024-01-02', '2024-01-03', '2024-02-01'] | ['2024-01-01', '2024-01-02', '2024-01-03'] | Failed |
| exdate outside rule | ['2024-01-01', '2024-01-04', '2024-01-07'] | ['2024-01-01', '2024-01-04', '2024-01-07'] | Passed |
SHA-256 / 8775dd54d4371ca43fb60aef70c1490be30c21518e273bd96803d017d9fdd9c1
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, count, rdates, exdates):
start = dt.date.fromisoformat(dtstart)
excluded = {dt.date.fromisoformat(x[:10]) for x in exdates}
rule = [start + dt.timedelta(days=k * interval) for k in range(count)]
extra = [dt.date.fromisoformat(x) for x in rdates]
rule = rule
merged = [d for d in rule + extra if d not in excluded]
result = sorted(set(merged))
return [d.isoformat() for d in result]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: exdate does not extend count',
['2024-03-01', 1, 5, [], ['2024-03-03']],
['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05']),
('timed exdate',
['2024-03-01', 2, 4, [], ['2024-03-05T09:30:00']],
['2024-03-01', '2024-03-03', '2024-03-07']),
('midnight exdate', ['2024-03-01', 1, 3, [], ['2024-03-02T00:00:00']], ['2024-03-01', '2024-03-03']),
('rdate equal to rule date',
['2024-01-01', 7, 3, ['2024-01-08'], []],
['2024-01-01', '2024-01-08', '2024-01-15']),
('rdate before dtstart',
['2024-01-10', 1, 3, ['2024-01-02'], []],
['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03']),
('exdate outside rule',
['2024-01-01', 3, 3, [], ['2024-01-02']],
['2024-01-01', '2024-01-04', '2024-01-07'])],
[('midnight exdate', ['2024-03-01', 1, 3, [], ['2024-03-02T00:00:00']], ['2024-03-01', '2024-03-03']),
('rdate equal to rule date',
['2024-01-01', 7, 3, ['2024-01-08'], []],
['2024-01-01', '2024-01-08', '2024-01-15']),
('rdate before dtstart',
['2024-01-10', 1, 3, ['2024-01-02'], []],
['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03']),
('exdate outside rule',
['2024-01-01', 3, 3, [], ['2024-01-02']],
['2024-01-01', '2024-01-04', '2024-01-07']),
('rdate between instances',
['2024-05-01', 10, 3, ['2024-05-05', '2024-05-30'], ['2024-05-11']],
['2024-05-01', '2024-05-05', '2024-05-21', '2024-05-30']),
('count zero with rdate', ['2024-01-01', 1, 0, ['2024-01-03'], []], ['2024-01-03'])],
[('rdate before dtstart',
['2024-01-10', 1, 3, ['2024-01-02'], []],
['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03']),
('exdate outside rule',
['2024-01-01', 3, 3, [], ['2024-01-02']],
['2024-01-01', '2024-01-04', '2024-01-07']),
('rdate between instances',
['2024-05-01', 10, 3, ['2024-05-05', '2024-05-30'], ['2024-05-11']],
['2024-05-01', '2024-05-05', '2024-05-21', '2024-05-30']),
('count zero with rdate', ['2024-01-01', 1, 0, ['2024-01-03'], []], ['2024-01-03']),
('duplicate rdates and timed exdate',
['2024-02-27', 1, 4, ['2024-03-05', '2024-03-05'], ['2024-02-28T12:00:00']],
['2024-02-27', '2024-02-29', '2024-03-01', '2024-03-05']),
('all excluded', ['2024-07-01', 1, 2, [], ['2024-07-01', '2024-07-02']], [])],
[('exdate outside rule',
['2024-01-01', 3, 3, [], ['2024-01-02']],
['2024-01-01', '2024-01-04', '2024-01-07']),
('rdate between instances',
['2024-05-01', 10, 3, ['2024-05-05', '2024-05-30'], ['2024-05-11']],
['2024-05-01', '2024-05-05', '2024-05-21', '2024-05-30']),
('count zero with rdate', ['2024-01-01', 1, 0, ['2024-01-03'], []], ['2024-01-03']),
('duplicate rdates and timed exdate',
['2024-02-27', 1, 4, ['2024-03-05', '2024-03-05'], ['2024-02-28T12:00:00']],
['2024-02-27', '2024-02-29', '2024-03-01', '2024-03-05']),
('all excluded', ['2024-07-01', 1, 2, [], ['2024-07-01', '2024-07-02']], []),
('regression: exdate does not extend count',
['2024-03-01', 1, 5, [], ['2024-03-03']],
['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05']),
('timed exdate',
['2024-03-01', 2, 4, [], ['2024-03-05T09:30:00']],
['2024-03-01', '2024-03-03', '2024-03-07']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03'])],
[('count zero with rdate', ['2024-01-01', 1, 0, ['2024-01-03'], []], ['2024-01-03']),
('duplicate rdates and timed exdate',
['2024-02-27', 1, 4, ['2024-03-05', '2024-03-05'], ['2024-02-28T12:00:00']],
['2024-02-27', '2024-02-29', '2024-03-01', '2024-03-05']),
('all excluded', ['2024-07-01', 1, 2, [], ['2024-07-01', '2024-07-02']], []),
('regression: exdate does not extend count',
['2024-03-01', 1, 5, [], ['2024-03-03']],
['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05']),
('timed exdate',
['2024-03-01', 2, 4, [], ['2024-03-05T09:30:00']],
['2024-03-01', '2024-03-03', '2024-03-07']),
('midnight exdate', ['2024-03-01', 1, 3, [], ['2024-03-02T00:00:00']], ['2024-03-01', '2024-03-03']),
('rdate equal to rule date',
['2024-01-01', 7, 3, ['2024-01-08'], []],
['2024-01-01', '2024-01-08', '2024-01-15']),
('exdate removes rdate',
['2024-01-01', 1, 3, ['2024-02-01'], ['2024-02-01']],
['2024-01-01', '2024-01-02', '2024-01-03'])]]
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: exdate does not extend count | ['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05'] | ['2024-03-01', '2024-03-02', '2024-03-04', '2024-03-05'] | Passed |
| timed exdate | ['2024-03-01', '2024-03-03', '2024-03-07'] | ['2024-03-01', '2024-03-03', '2024-03-07'] | Passed |
| midnight exdate | ['2024-03-01', '2024-03-03'] | ['2024-03-01', '2024-03-03'] | Passed |
| rdate equal to rule date | ['2024-01-01', '2024-01-08', '2024-01-15'] | ['2024-01-01', '2024-01-08', '2024-01-15'] | Passed |
| rdate before dtstart | ['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12'] | ['2024-01-02', '2024-01-10', '2024-01-11', '2024-01-12'] | Passed |
| exdate removes rdate | ['2024-01-01', '2024-01-02', '2024-01-03'] | ['2024-01-01', '2024-01-02', '2024-01-03'] | Passed |
| exdate outside rule | ['2024-01-01', '2024-01-04', '2024-01-07'] | ['2024-01-01', '2024-01-04', '2024-01-07'] | Passed |
SHA-256 / 8ccb0df371148241cc9cb68cf8bb6d6396d8e3b76aa9111ecceacbc76e5f4cee
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.277480+00:00.
Case digest / 6ec06cb4823e7cd0a66466fe4ecf11c7450f6ecb6d6a667a3281ecd6b02dd9d5