FAILURE MAP
← Case archive

FA-77021 / Calendar recurrence rules / Open access

Splitting a series for a this-and-following edit: tail count · case 01

The tail series repeats the full original COUNT and extends the series.

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

ROOT CAUSE

The tail count is not reduced by the occurrences kept in the head.

VERIFIED REPAIR

At the tail count decision use `count - k`, leaving the other decision sites of the model unchanged.

Unsuccessful approach: The partial repair `count - k - 1` subtracts one extra occurrence and loses the last instance.

Case contract

A daily-interval series (dtstart, interval, and either count or until). Editing from 0-based occurrence k splits it: the head keeps occurrences 0..k-1 (count k, or until = its last retained occurrence date) and the tail starts at the original date of occurrence k with new_interval and the remaining count (or the original until). k <= 0 makes the head None; a split at or past the end makes the tail None. Return {"head": [dtstart, count, until] or None, "tail": [start, interval, count, until] or None}.

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, until, k, new_interval):
    start = dt.date.fromisoformat(dtstart)
    until_d = dt.date.fromisoformat(until) if until else None
    tail_start = start + dt.timedelta(days=k * interval)
    if (count is not None and k >= count) or (until_d is not None and tail_start > until_d):
        tail = None
    else:
        tail = [tail_start.isoformat(), new_interval, count if count is not None else None, until]
    if k <= 0:
        head = None
    elif count is not None:
        head = [dtstart, k, None]
    else:
        head = [dtstart, None, (start + dt.timedelta(days=(k - 1) * interval)).isoformat()]
    return {'head': head, 'tail': tail}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: count series split at 3',
   ['2024-01-01', 2, 10, None, 3, 7],
   {'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}),
  ('until series split at 2',
   ['2024-01-01', 3, None, '2024-02-01', 2, 1],
   {'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']}),
  ('split at first occurrence',
   ['2024-01-01', 1, 5, None, 0, 2],
   {'head': None, 'tail': ['2024-01-01', 2, 5, None]}),
  ('until split at first',
   ['2024-03-01', 7, None, '2024-06-01', 0, 14],
   {'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']}),
  ('split exactly at count',
   ['2024-01-01', 1, 4, None, 4, 2],
   {'head': ['2024-01-01', 4, None], 'tail': None}),
  ('split past until',
   ['2024-01-01', 5, None, '2024-01-20', 5, 2],
   {'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}),
  ('split at last until occurrence',
   ['2024-01-01', 5, None, '2024-01-21', 4, 1],
   {'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']})],
 [('split at first occurrence',
   ['2024-01-01', 1, 5, None, 0, 2],
   {'head': None, 'tail': ['2024-01-01', 2, 5, None]}),
  ('until split at first',
   ['2024-03-01', 7, None, '2024-06-01', 0, 14],
   {'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']}),
  ('split exactly at count',
   ['2024-01-01', 1, 4, None, 4, 2],
   {'head': ['2024-01-01', 4, None], 'tail': None}),
  ('split past until',
   ['2024-01-01', 5, None, '2024-01-20', 5, 2],
   {'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}),
  ('split at last until occurrence',
   ['2024-01-01', 5, None, '2024-01-21', 4, 1],
   {'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}),
  ('count split near end',
   ['2024-05-10', 1, 6, None, 5, 3],
   {'head': ['2024-05-10', 5, None], 'tail': ['2024-05-15', 3, 1, None]}),
  ('until split mid',
   ['2024-05-10', 4, None, '2024-07-01', 6, 2],
   {'head': ['2024-05-10', None, '2024-05-30'], 'tail': ['2024-06-03', 2, None, '2024-07-01']})],
 [('split exactly at count',
   ['2024-01-01', 1, 4, None, 4, 2],
   {'head': ['2024-01-01', 4, None], 'tail': None}),
  ('split past until',
   ['2024-01-01', 5, None, '2024-01-20', 5, 2],
   {'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}),
  ('split at last until occurrence',
   ['2024-01-01', 5, None, '2024-01-21', 4, 1],
   {'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}),
  ('count split near end',
   ['2024-05-10', 1, 6, None, 5, 3],
   {'head': ['2024-05-10', 5, None], 'tail': ['2024-05-15', 3, 1, None]}),
  ('until split mid',
   ['2024-05-10', 4, None, '2024-07-01', 6, 2],
   {'head': ['2024-05-10', None, '2024-05-30'], 'tail': ['2024-06-03', 2, None, '2024-07-01']}),
  ('interval 1 count split',
   ['2024-12-30', 1, 8, None, 2, 1],
   {'head': ['2024-12-30', 2, None], 'tail': ['2025-01-01', 1, 6, None]}),
  ('split beyond count', ['2024-01-01', 1, 3, None, 7, 2], {'head': ['2024-01-01', 7, None], 'tail': None})],
 [('split at last until occurrence',
   ['2024-01-01', 5, None, '2024-01-21', 4, 1],
   {'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}),
  ('count split near end',
   ['2024-05-10', 1, 6, None, 5, 3],
   {'head': ['2024-05-10', 5, None], 'tail': ['2024-05-15', 3, 1, None]}),
  ('until split mid',
   ['2024-05-10', 4, None, '2024-07-01', 6, 2],
   {'head': ['2024-05-10', None, '2024-05-30'], 'tail': ['2024-06-03', 2, None, '2024-07-01']}),
  ('interval 1 count split',
   ['2024-12-30', 1, 8, None, 2, 1],
   {'head': ['2024-12-30', 2, None], 'tail': ['2025-01-01', 1, 6, None]}),
  ('split beyond count', ['2024-01-01', 1, 3, None, 7, 2], {'head': ['2024-01-01', 7, None], 'tail': None}),
  ('regression: count series split at 3',
   ['2024-01-01', 2, 10, None, 3, 7],
   {'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}),
  ('until series split at 2',
   ['2024-01-01', 3, None, '2024-02-01', 2, 1],
   {'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']})],
 [('until split mid',
   ['2024-05-10', 4, None, '2024-07-01', 6, 2],
   {'head': ['2024-05-10', None, '2024-05-30'], 'tail': ['2024-06-03', 2, None, '2024-07-01']}),
  ('interval 1 count split',
   ['2024-12-30', 1, 8, None, 2, 1],
   {'head': ['2024-12-30', 2, None], 'tail': ['2025-01-01', 1, 6, None]}),
  ('split beyond count', ['2024-01-01', 1, 3, None, 7, 2], {'head': ['2024-01-01', 7, None], 'tail': None}),
  ('regression: count series split at 3',
   ['2024-01-01', 2, 10, None, 3, 7],
   {'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}),
  ('until series split at 2',
   ['2024-01-01', 3, None, '2024-02-01', 2, 1],
   {'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']}),
  ('split at first occurrence',
   ['2024-01-01', 1, 5, None, 0, 2],
   {'head': None, 'tail': ['2024-01-01', 2, 5, None]}),
  ('until split at first',
   ['2024-03-01', 7, None, '2024-06-01', 0, 14],
   {'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']})]]
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: count series split at 3{'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 10, None]}{'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}Failed
until series split at 2{'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']}{'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']}Passed
split at first occurrence{'head': None, 'tail': ['2024-01-01', 2, 5, None]}{'head': None, 'tail': ['2024-01-01', 2, 5, None]}Passed
until split at first{'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']}{'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']}Passed
split exactly at count{'head': ['2024-01-01', 4, None], 'tail': None}{'head': ['2024-01-01', 4, None], 'tail': None}Passed
split past until{'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}{'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}Passed
split at last until occurrence{'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}{'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}Passed

SHA-256 / 1c6ccb91e53d4ffc8c4b387e57db31ea074c544f6593e794014e6a255cca3a73

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, until, k, new_interval):
    start = dt.date.fromisoformat(dtstart)
    until_d = dt.date.fromisoformat(until) if until else None
    tail_start = start + dt.timedelta(days=k * interval)
    if (count is not None and k >= count) or (until_d is not None and tail_start > until_d):
        tail = None
    else:
        tail = [tail_start.isoformat(), new_interval, count - k - 1 if count is not None else None, until]
    if k <= 0:
        head = None
    elif count is not None:
        head = [dtstart, k, None]
    else:
        head = [dtstart, None, (start + dt.timedelta(days=(k - 1) * interval)).isoformat()]
    return {'head': head, 'tail': tail}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: count series split at 3',
   ['2024-01-01', 2, 10, None, 3, 7],
   {'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}),
  ('until series split at 2',
   ['2024-01-01', 3, None, '2024-02-01', 2, 1],
   {'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']}),
  ('split at first occurrence',
   ['2024-01-01', 1, 5, None, 0, 2],
   {'head': None, 'tail': ['2024-01-01', 2, 5, None]}),
  ('until split at first',
   ['2024-03-01', 7, None, '2024-06-01', 0, 14],
   {'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']}),
  ('split exactly at count',
   ['2024-01-01', 1, 4, None, 4, 2],
   {'head': ['2024-01-01', 4, None], 'tail': None}),
  ('split past until',
   ['2024-01-01', 5, None, '2024-01-20', 5, 2],
   {'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}),
  ('split at last until occurrence',
   ['2024-01-01', 5, None, '2024-01-21', 4, 1],
   {'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']})],
 [('split at first occurrence',
   ['2024-01-01', 1, 5, None, 0, 2],
   {'head': None, 'tail': ['2024-01-01', 2, 5, None]}),
  ('until split at first',
   ['2024-03-01', 7, None, '2024-06-01', 0, 14],
   {'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']}),
  ('split exactly at count',
   ['2024-01-01', 1, 4, None, 4, 2],
   {'head': ['2024-01-01', 4, None], 'tail': None}),
  ('split past until',
   ['2024-01-01', 5, None, '2024-01-20', 5, 2],
   {'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}),
  ('split at last until occurrence',
   ['2024-01-01', 5, None, '2024-01-21', 4, 1],
   {'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}),
  ('count split near end',
   ['2024-05-10', 1, 6, None, 5, 3],
   {'head': ['2024-05-10', 5, None], 'tail': ['2024-05-15', 3, 1, None]}),
  ('until split mid',
   ['2024-05-10', 4, None, '2024-07-01', 6, 2],
   {'head': ['2024-05-10', None, '2024-05-30'], 'tail': ['2024-06-03', 2, None, '2024-07-01']})],
 [('split exactly at count',
   ['2024-01-01', 1, 4, None, 4, 2],
   {'head': ['2024-01-01', 4, None], 'tail': None}),
  ('split past until',
   ['2024-01-01', 5, None, '2024-01-20', 5, 2],
   {'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}),
  ('split at last until occurrence',
   ['2024-01-01', 5, None, '2024-01-21', 4, 1],
   {'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}),
  ('count split near end',
   ['2024-05-10', 1, 6, None, 5, 3],
   {'head': ['2024-05-10', 5, None], 'tail': ['2024-05-15', 3, 1, None]}),
  ('until split mid',
   ['2024-05-10', 4, None, '2024-07-01', 6, 2],
   {'head': ['2024-05-10', None, '2024-05-30'], 'tail': ['2024-06-03', 2, None, '2024-07-01']}),
  ('interval 1 count split',
   ['2024-12-30', 1, 8, None, 2, 1],
   {'head': ['2024-12-30', 2, None], 'tail': ['2025-01-01', 1, 6, None]}),
  ('split beyond count', ['2024-01-01', 1, 3, None, 7, 2], {'head': ['2024-01-01', 7, None], 'tail': None})],
 [('split at last until occurrence',
   ['2024-01-01', 5, None, '2024-01-21', 4, 1],
   {'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}),
  ('count split near end',
   ['2024-05-10', 1, 6, None, 5, 3],
   {'head': ['2024-05-10', 5, None], 'tail': ['2024-05-15', 3, 1, None]}),
  ('until split mid',
   ['2024-05-10', 4, None, '2024-07-01', 6, 2],
   {'head': ['2024-05-10', None, '2024-05-30'], 'tail': ['2024-06-03', 2, None, '2024-07-01']}),
  ('interval 1 count split',
   ['2024-12-30', 1, 8, None, 2, 1],
   {'head': ['2024-12-30', 2, None], 'tail': ['2025-01-01', 1, 6, None]}),
  ('split beyond count', ['2024-01-01', 1, 3, None, 7, 2], {'head': ['2024-01-01', 7, None], 'tail': None}),
  ('regression: count series split at 3',
   ['2024-01-01', 2, 10, None, 3, 7],
   {'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}),
  ('until series split at 2',
   ['2024-01-01', 3, None, '2024-02-01', 2, 1],
   {'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']})],
 [('until split mid',
   ['2024-05-10', 4, None, '2024-07-01', 6, 2],
   {'head': ['2024-05-10', None, '2024-05-30'], 'tail': ['2024-06-03', 2, None, '2024-07-01']}),
  ('interval 1 count split',
   ['2024-12-30', 1, 8, None, 2, 1],
   {'head': ['2024-12-30', 2, None], 'tail': ['2025-01-01', 1, 6, None]}),
  ('split beyond count', ['2024-01-01', 1, 3, None, 7, 2], {'head': ['2024-01-01', 7, None], 'tail': None}),
  ('regression: count series split at 3',
   ['2024-01-01', 2, 10, None, 3, 7],
   {'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}),
  ('until series split at 2',
   ['2024-01-01', 3, None, '2024-02-01', 2, 1],
   {'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']}),
  ('split at first occurrence',
   ['2024-01-01', 1, 5, None, 0, 2],
   {'head': None, 'tail': ['2024-01-01', 2, 5, None]}),
  ('until split at first',
   ['2024-03-01', 7, None, '2024-06-01', 0, 14],
   {'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']})]]
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: count series split at 3{'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 6, None]}{'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}Failed
until series split at 2{'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']}{'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']}Passed
split at first occurrence{'head': None, 'tail': ['2024-01-01', 2, 4, None]}{'head': None, 'tail': ['2024-01-01', 2, 5, None]}Failed
until split at first{'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']}{'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']}Passed
split exactly at count{'head': ['2024-01-01', 4, None], 'tail': None}{'head': ['2024-01-01', 4, None], 'tail': None}Passed
split past until{'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}{'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}Passed
split at last until occurrence{'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}{'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}Passed

SHA-256 / 6f05d74cc2cc6a8ef1cd48b03681363098ee0f78e4fdbdf23e6b2ab57a988c63

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, until, k, new_interval):
    start = dt.date.fromisoformat(dtstart)
    until_d = dt.date.fromisoformat(until) if until else None
    tail_start = start + dt.timedelta(days=k * interval)
    if (count is not None and k >= count) or (until_d is not None and tail_start > until_d):
        tail = None
    else:
        tail = [tail_start.isoformat(), new_interval, count - k if count is not None else None, until]
    if k <= 0:
        head = None
    elif count is not None:
        head = [dtstart, k, None]
    else:
        head = [dtstart, None, (start + dt.timedelta(days=(k - 1) * interval)).isoformat()]
    return {'head': head, 'tail': tail}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: count series split at 3',
   ['2024-01-01', 2, 10, None, 3, 7],
   {'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}),
  ('until series split at 2',
   ['2024-01-01', 3, None, '2024-02-01', 2, 1],
   {'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']}),
  ('split at first occurrence',
   ['2024-01-01', 1, 5, None, 0, 2],
   {'head': None, 'tail': ['2024-01-01', 2, 5, None]}),
  ('until split at first',
   ['2024-03-01', 7, None, '2024-06-01', 0, 14],
   {'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']}),
  ('split exactly at count',
   ['2024-01-01', 1, 4, None, 4, 2],
   {'head': ['2024-01-01', 4, None], 'tail': None}),
  ('split past until',
   ['2024-01-01', 5, None, '2024-01-20', 5, 2],
   {'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}),
  ('split at last until occurrence',
   ['2024-01-01', 5, None, '2024-01-21', 4, 1],
   {'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']})],
 [('split at first occurrence',
   ['2024-01-01', 1, 5, None, 0, 2],
   {'head': None, 'tail': ['2024-01-01', 2, 5, None]}),
  ('until split at first',
   ['2024-03-01', 7, None, '2024-06-01', 0, 14],
   {'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']}),
  ('split exactly at count',
   ['2024-01-01', 1, 4, None, 4, 2],
   {'head': ['2024-01-01', 4, None], 'tail': None}),
  ('split past until',
   ['2024-01-01', 5, None, '2024-01-20', 5, 2],
   {'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}),
  ('split at last until occurrence',
   ['2024-01-01', 5, None, '2024-01-21', 4, 1],
   {'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}),
  ('count split near end',
   ['2024-05-10', 1, 6, None, 5, 3],
   {'head': ['2024-05-10', 5, None], 'tail': ['2024-05-15', 3, 1, None]}),
  ('until split mid',
   ['2024-05-10', 4, None, '2024-07-01', 6, 2],
   {'head': ['2024-05-10', None, '2024-05-30'], 'tail': ['2024-06-03', 2, None, '2024-07-01']})],
 [('split exactly at count',
   ['2024-01-01', 1, 4, None, 4, 2],
   {'head': ['2024-01-01', 4, None], 'tail': None}),
  ('split past until',
   ['2024-01-01', 5, None, '2024-01-20', 5, 2],
   {'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}),
  ('split at last until occurrence',
   ['2024-01-01', 5, None, '2024-01-21', 4, 1],
   {'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}),
  ('count split near end',
   ['2024-05-10', 1, 6, None, 5, 3],
   {'head': ['2024-05-10', 5, None], 'tail': ['2024-05-15', 3, 1, None]}),
  ('until split mid',
   ['2024-05-10', 4, None, '2024-07-01', 6, 2],
   {'head': ['2024-05-10', None, '2024-05-30'], 'tail': ['2024-06-03', 2, None, '2024-07-01']}),
  ('interval 1 count split',
   ['2024-12-30', 1, 8, None, 2, 1],
   {'head': ['2024-12-30', 2, None], 'tail': ['2025-01-01', 1, 6, None]}),
  ('split beyond count', ['2024-01-01', 1, 3, None, 7, 2], {'head': ['2024-01-01', 7, None], 'tail': None})],
 [('split at last until occurrence',
   ['2024-01-01', 5, None, '2024-01-21', 4, 1],
   {'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}),
  ('count split near end',
   ['2024-05-10', 1, 6, None, 5, 3],
   {'head': ['2024-05-10', 5, None], 'tail': ['2024-05-15', 3, 1, None]}),
  ('until split mid',
   ['2024-05-10', 4, None, '2024-07-01', 6, 2],
   {'head': ['2024-05-10', None, '2024-05-30'], 'tail': ['2024-06-03', 2, None, '2024-07-01']}),
  ('interval 1 count split',
   ['2024-12-30', 1, 8, None, 2, 1],
   {'head': ['2024-12-30', 2, None], 'tail': ['2025-01-01', 1, 6, None]}),
  ('split beyond count', ['2024-01-01', 1, 3, None, 7, 2], {'head': ['2024-01-01', 7, None], 'tail': None}),
  ('regression: count series split at 3',
   ['2024-01-01', 2, 10, None, 3, 7],
   {'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}),
  ('until series split at 2',
   ['2024-01-01', 3, None, '2024-02-01', 2, 1],
   {'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']})],
 [('until split mid',
   ['2024-05-10', 4, None, '2024-07-01', 6, 2],
   {'head': ['2024-05-10', None, '2024-05-30'], 'tail': ['2024-06-03', 2, None, '2024-07-01']}),
  ('interval 1 count split',
   ['2024-12-30', 1, 8, None, 2, 1],
   {'head': ['2024-12-30', 2, None], 'tail': ['2025-01-01', 1, 6, None]}),
  ('split beyond count', ['2024-01-01', 1, 3, None, 7, 2], {'head': ['2024-01-01', 7, None], 'tail': None}),
  ('regression: count series split at 3',
   ['2024-01-01', 2, 10, None, 3, 7],
   {'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}),
  ('until series split at 2',
   ['2024-01-01', 3, None, '2024-02-01', 2, 1],
   {'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']}),
  ('split at first occurrence',
   ['2024-01-01', 1, 5, None, 0, 2],
   {'head': None, 'tail': ['2024-01-01', 2, 5, None]}),
  ('until split at first',
   ['2024-03-01', 7, None, '2024-06-01', 0, 14],
   {'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']})]]
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: count series split at 3{'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}{'head': ['2024-01-01', 3, None], 'tail': ['2024-01-07', 7, 7, None]}Passed
until series split at 2{'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']}{'head': ['2024-01-01', None, '2024-01-04'], 'tail': ['2024-01-07', 1, None, '2024-02-01']}Passed
split at first occurrence{'head': None, 'tail': ['2024-01-01', 2, 5, None]}{'head': None, 'tail': ['2024-01-01', 2, 5, None]}Passed
until split at first{'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']}{'head': None, 'tail': ['2024-03-01', 14, None, '2024-06-01']}Passed
split exactly at count{'head': ['2024-01-01', 4, None], 'tail': None}{'head': ['2024-01-01', 4, None], 'tail': None}Passed
split past until{'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}{'head': ['2024-01-01', None, '2024-01-21'], 'tail': None}Passed
split at last until occurrence{'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}{'head': ['2024-01-01', None, '2024-01-16'], 'tail': ['2024-01-21', 1, None, '2024-01-21']}Passed

SHA-256 / a31cc8a12282fe18fc93629b6ffef78fbe8addce38bf7d59ab4591b74027d69d

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

Case digest / fb96ff9e2c2e077a3a5efbcbbfdeb07c94ba226f63f158b9bd87312c1b4a6fc0