{"abstract":"A missed alarm for a meeting that has not started yet is silently dropped.","category":"Calendar recurrence rules","checks":8,"contract":"Occurrences start at dtstart + k*interval_hours for k < count. Each has one alarm at start + trigger_min minutes (negative means before the start). Occurrences whose start string (YYYY-MM-DDTHH:MM) is in acknowledged have no alarm. An alarm due at or before now is delivered at now if the occurrence has not started yet (start > now), otherwise dropped. Alarms due after now + horizon_hours are not scheduled. Return [occurrence_start, fire_time] pairs in series order.","contract_signature":"dtstart, interval_hours, count, trigger_min, acknowledged, now, horizon_hours","evaluation_group":"w2-calendar-recurrence-rules-recurring-alarm-schedule","failed_approach":"The partial repair `s >= now_t` also catches up an occurrence starting exactly now, which the contract treats as started.","family":"w2-calendar-recurrence-rules-recurring-alarm-schedule-late-catchup","id":"FA-77191","implementations":{"attempt":{"sha256":"d51f7ec3650d0fa773aa7e38d6e9581773182bf13663cca030b928e9d9aa3e14","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport datetime as dt\nimport calendar\nN = 1\nobservations = []\ndef solve(dtstart, interval_hours, count, trigger_min, acknowledged, now, horizon_hours):\n    first = dt.datetime.fromisoformat(dtstart)\n    now_t = dt.datetime.fromisoformat(now)\n    acked = set(acknowledged)\n    end = now_t + dt.timedelta(hours=horizon_hours)\n    out = []\n    for k in range(count):\n        s = first + dt.timedelta(hours=k * interval_hours)\n        fire = s + dt.timedelta(minutes=trigger_min)\n        if fire > end:\n            break\n        if s.isoformat(timespec='minutes') in acked:\n            continue\n        if fire <= now_t:\n            if s >= now_t:\n                fire = now_t\n            else:\n                continue\n        out.append([s.isoformat(timespec='minutes'), fire.isoformat(timespec='minutes')])\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression: negative trigger',\n   ['2024-01-01T09:00', 24, 3, -15, [], '2024-01-01T00:00', 72],\n   [['2024-01-01T09:00', '2024-01-01T08:45'],\n    ['2024-01-02T09:00', '2024-01-02T08:45'],\n    ['2024-01-03T09:00', '2024-01-03T08:45']]),\n  ('positive trigger',\n   ['2024-01-01T09:00', 24, 3, 10, [], '2024-01-01T00:00', 72],\n   [['2024-01-01T09:00', '2024-01-01T09:10'],\n    ['2024-01-02T09:00', '2024-01-02T09:10'],\n    ['2024-01-03T09:00', '2024-01-03T09:10']]),\n  ('horizon edge with lead time',\n   ['2024-01-01T10:00', 1, 6, -60, [], '2024-01-01T08:00', 4],\n   [['2024-01-01T10:00', '2024-01-01T09:00'],\n    ['2024-01-01T11:00', '2024-01-01T10:00'],\n    ['2024-01-01T12:00', '2024-01-01T11:00'],\n    ['2024-01-01T13:00', '2024-01-01T12:00']]),\n  ('horizon exact',\n   ['2024-01-01T10:00', 2, 5, 0, [], '2024-01-01T08:00', 4],\n   [['2024-01-01T10:00', '2024-01-01T10:00'], ['2024-01-01T12:00', '2024-01-01T12:00']]),\n  ('acknowledged occurrence',\n   ['2024-01-01T09:00', 4, 4, -30, ['2024-01-01T13:00'], '2024-01-01T00:00', 48],\n   [['2024-01-01T09:00', '2024-01-01T08:30'],\n    ['2024-01-01T17:00', '2024-01-01T16:30'],\n    ['2024-01-01T21:00', '2024-01-01T20:30']]),\n  ('missed alarm catch-up',\n   ['2024-01-01T09:00', 24, 2, -120, [], '2024-01-01T08:30', 48],\n   [['2024-01-01T09:00', '2024-01-01T08:30'], ['2024-01-02T09:00', '2024-01-02T07:00']]),\n  ('missed long before start',\n   ['2024-01-01T12:00', 24, 2, -1440, [], '2024-01-01T09:00', 48],\n   [['2024-01-01T12:00', '2024-01-01T09:00'], ['2024-01-02T12:00', '2024-01-01T12:00']]),\n  ('occurrence starting now',\n   ['2024-01-01T09:00', 24, 2, -10, [], '2024-01-01T09:00', 48],\n   [['2024-01-02T09:00', '2024-01-02T08:50']])],\n [('horizon edge with lead time',\n   ['2024-01-01T10:00', 1, 6, -60, [], '2024-01-01T08:00', 4],\n   [['2024-01-01T10:00', '2024-01-01T09:00'],\n    ['2024-01-01T11:00', '2024-01-01T10:00'],\n    ['2024-01-01T12:00', '2024-01-01T11:00'],\n    ['2024-01-01T13:00', '2024-01-01T12:00']]),\n  ('horizon exact',\n   ['2024-01-01T10:00', 2, 5, 0, [], '2024-01-01T08:00', 4],\n   [['2024-01-01T10:00', '2024-01-01T10:00'], ['2024-01-01T12:00', '2024-01-01T12:00']]),\n  ('acknowledged occurrence',\n   ['2024-01-01T09:00', 4, 4, -30, ['2024-01-01T13:00'], '2024-01-01T00:00', 48],\n   [['2024-01-01T09:00', '2024-01-01T08:30'],\n    ['2024-01-01T17:00', '2024-01-01T16:30'],\n    ['2024-01-01T21:00', '2024-01-01T20:30']]),\n  ('missed alarm catch-up',\n   ['2024-01-01T09:00', 24, 2, -120, [], '2024-01-01T08:30', 48],\n   [['2024-01-01T09:00', '2024-01-01T08:30'], ['2024-01-02T09:00', '2024-01-02T07:00']]),\n  ('missed long before start',\n   ['2024-01-01T12:00', 24, 2, -1440, [], '2024-01-01T09:00', 48],\n   [['2024-01-01T12:00', '2024-01-01T09:00'], ['2024-01-02T12:00', '2024-01-01T12:00']]),\n  ('occurrence starting now',\n   ['2024-01-01T09:00', 24, 2, -10, [], '2024-01-01T09:00', 48],\n   [['2024-01-02T09:00', '2024-01-02T08:50']]),\n  ('started occurrence dropped',\n   ['2024-01-01T09:00', 1, 4, -5, [], '2024-01-01T10:30', 4],\n   [['2024-01-01T11:00', '2024-01-01T10:55'], ['2024-01-01T12:00', '2024-01-01T11:55']])],\n [('acknowledged occurrence',\n   ['2024-01-01T09:00', 4, 4, -30, ['2024-01-01T13:00'], '2024-01-01T00:00', 48],\n   [['2024-01-01T09:00', '2024-01-01T08:30'],\n    ['2024-01-01T17:00', '2024-01-01T16:30'],\n    ['2024-01-01T21:00', '2024-01-01T20:30']]),\n  ('missed alarm catch-up',\n   ['2024-01-01T09:00', 24, 2, -120, [], '2024-01-01T08:30', 48],\n   [['2024-01-01T09:00', '2024-01-01T08:30'], ['2024-01-02T09:00', '2024-01-02T07:00']]),\n  ('missed long before start',\n   ['2024-01-01T12:00', 24, 2, -1440, [], '2024-01-01T09:00', 48],\n   [['2024-01-01T12:00', '2024-01-01T09:00'], ['2024-01-02T12:00', '2024-01-01T12:00']]),\n  ('occurrence starting now',\n   ['2024-01-01T09:00', 24, 2, -10, [], '2024-01-01T09:00', 48],\n   [['2024-01-02T09:00', '2024-01-02T08:50']]),\n  ('started occurrence dropped',\n   ['2024-01-01T09:00', 1, 4, -5, [], '2024-01-01T10:30', 4],\n   [['2024-01-01T11:00', '2024-01-01T10:55'], ['2024-01-01T12:00', '2024-01-01T11:55']]),\n  ('ack and catch-up mix',\n   ['2024-02-01T09:00', 3, 4, -240, ['2024-02-01T12:00'], '2024-02-01T08:00', 12],\n   [['2024-02-01T09:00', '2024-02-01T08:00'],\n    ['2024-02-01T15:00', '2024-02-01T11:00'],\n    ['2024-02-01T18:00', '2024-02-01T14:00']]),\n  ('zero trigger all future',\n   ['2024-03-01T06:00', 6, 3, 0, ['2024-03-01T06:00'], '2024-03-01T00:00', 24],\n   [['2024-03-01T12:00', '2024-03-01T12:00'], ['2024-03-01T18:00', '2024-03-01T18:00']])],\n [('missed long before start',\n   ['2024-01-01T12:00', 24, 2, -1440, [], '2024-01-01T09:00', 48],\n   [['2024-01-01T12:00', '2024-01-01T09:00'], ['2024-01-02T12:00', '2024-01-01T12:00']]),\n  ('occurrence starting now',\n   ['2024-01-01T09:00', 24, 2, -10, [], '2024-01-01T09:00', 48],\n   [['2024-01-02T09:00', '2024-01-02T08:50']]),\n  ('started occurrence dropped',\n   ['2024-01-01T09:00', 1, 4, -5, [], '2024-01-01T10:30', 4],\n   [['2024-01-01T11:00', '2024-01-01T10:55'], ['2024-01-01T12:00', '2024-01-01T11:55']]),\n  ('ack and catch-up mix',\n   ['2024-02-01T09:00', 3, 4, -240, ['2024-02-01T12:00'], '2024-02-01T08:00', 12],\n   [['2024-02-01T09:00', '2024-02-01T08:00'],\n    ['2024-02-01T15:00', '2024-02-01T11:00'],\n    ['2024-02-01T18:00', '2024-02-01T14:00']]),\n  ('zero trigger all future',\n   ['2024-03-01T06:00', 6, 3, 0, ['2024-03-01T06:00'], '2024-03-01T00:00', 24],\n   [['2024-03-01T12:00', '2024-03-01T12:00'], ['2024-03-01T18:00', '2024-03-01T18:00']]),\n  ('regression: negative trigger',\n   ['2024-01-01T09:00', 24, 3, -15, [], '2024-01-01T00:00', 72],\n   [['2024-01-01T09:00', '2024-01-01T08:45'],\n    ['2024-01-02T09:00', '2024-01-02T08:45'],\n    ['2024-01-03T09:00', '2024-01-03T08:45']]),\n  ('positive trigger',\n   ['2024-01-01T09:00', 24, 3, 10, [], '2024-01-01T00:00', 72],\n   [['2024-01-01T09:00', '2024-01-01T09:10'],\n    ['2024-01-02T09:00', '2024-01-02T09:10'],\n    ['2024-01-03T09:00', '2024-01-03T09:10']])],\n [('started occurrence dropped',\n   ['2024-01-01T09:00', 1, 4, -5, [], '2024-01-01T10:30', 4],\n   [['2024-01-01T11:00', '2024-01-01T10:55'], ['2024-01-01T12:00', '2024-01-01T11:55']]),\n  ('ack and catch-up mix',\n   ['2024-02-01T09:00', 3, 4, -240, ['2024-02-01T12:00'], '2024-02-01T08:00', 12],\n   [['2024-02-01T09:00', '2024-02-01T08:00'],\n    ['2024-02-01T15:00', '2024-02-01T11:00'],\n    ['2024-02-01T18:00', '2024-02-01T14:00']]),\n  ('zero trigger all future',\n   ['2024-03-01T06:00', 6, 3, 0, ['2024-03-01T06:00'], '2024-03-01T00:00', 24],\n   [['2024-03-01T12:00', '2024-03-01T12:00'], ['2024-03-01T18:00', '2024-03-01T18:00']]),\n  ('regression: negative trigger',\n   ['2024-01-01T09:00', 24, 3, -15, [], '2024-01-01T00:00', 72],\n   [['2024-01-01T09:00', '2024-01-01T08:45'],\n    ['2024-01-02T09:00', '2024-01-02T08:45'],\n    ['2024-01-03T09:00', '2024-01-03T08:45']]),\n  ('positive trigger',\n   ['2024-01-01T09:00', 24, 3, 10, [], '2024-01-01T00:00', 72],\n   [['2024-01-01T09:00', '2024-01-01T09:10'],\n    ['2024-01-02T09:00', '2024-01-02T09:10'],\n    ['2024-01-03T09:00', '2024-01-03T09:10']]),\n  ('horizon edge with lead time',\n   ['2024-01-01T10:00', 1, 6, -60, [], '2024-01-01T08:00', 4],\n   [['2024-01-01T10:00', '2024-01-01T09:00'],\n    ['2024-01-01T11:00', '2024-01-01T10:00'],\n    ['2024-01-01T12:00', '2024-01-01T11:00'],\n    ['2024-01-01T13:00', '2024-01-01T12:00']]),\n  ('horizon exact',\n   ['2024-01-01T10:00', 2, 5, 0, [], '2024-01-01T08:00', 4],\n   [['2024-01-01T10:00', '2024-01-01T10:00'], ['2024-01-01T12:00', '2024-01-01T12:00']]),\n  ('occurrence starting now',\n   ['2024-01-01T09:00', 24, 2, -10, [], '2024-01-01T09:00', 48],\n   [['2024-01-02T09:00', '2024-01-02T08:50']])]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"9038832f8706e1a86eab191d16300c930a3a90baaea726f027768b58dc9e66e7","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport datetime as dt\nimport calendar\nN = 1\nobservations = []\ndef solve(dtstart, interval_hours, count, trigger_min, acknowledged, now, horizon_hours):\n    first = dt.datetime.fromisoformat(dtstart)\n    now_t = dt.datetime.fromisoformat(now)\n    acked = set(acknowledged)\n    end = now_t + dt.timedelta(hours=horizon_hours)\n    out = []\n    for k in range(count):\n        s = first + dt.timedelta(hours=k * interval_hours)\n        fire = s + dt.timedelta(minutes=trigger_min)\n        if fire > end:\n            break\n        if s.isoformat(timespec='minutes') in acked:\n            continue\n        if fire <= now_t:\n            if fire > now_t - dt.timedelta(minutes=15):\n                fire = now_t\n            else:\n                continue\n        out.append([s.isoformat(timespec='minutes'), fire.isoformat(timespec='minutes')])\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression: negative trigger',\n   ['2024-01-01T09:00', 24, 3, -15, [], '2024-01-01T00:00', 72],\n   [['2024-01-01T09:00', '2024-01-01T08:45'],\n    ['2024-01-02T09:00', '2024-01-02T08:45'],\n    ['2024-01-03T09:00', '2024-01-03T08:45']]),\n  ('positive trigger',\n   ['2024-01-01T09:00', 24, 3, 10, [], '2024-01-01T00:00', 72],\n   [['2024-01-01T09:00', '2024-01-01T09:10'],\n    ['2024-01-02T09:00', '2024-01-02T09:10'],\n    ['2024-01-03T09:00', '2024-01-03T09:10']]),\n  ('horizon edge with lead time',\n   ['2024-01-01T10:00', 1, 6, -60, [], '2024-01-01T08:00', 4],\n   [['2024-01-01T10:00', '2024-01-01T09:00'],\n    ['2024-01-01T11:00', '2024-01-01T10:00'],\n    ['2024-01-01T12:00', '2024-01-01T11:00'],\n    ['2024-01-01T13:00', '2024-01-01T12:00']]),\n  ('horizon exact',\n   ['2024-01-01T10:00', 2, 5, 0, [], '2024-01-01T08:00', 4],\n   [['2024-01-01T10:00', '2024-01-01T10:00'], ['2024-01-01T12:00', '2024-01-01T12:00']]),\n  ('acknowledged occurrence',\n   ['2024-01-01T09:00', 4, 4, -30, ['2024-01-01T13:00'], '2024-01-01T00:00', 48],\n   [['2024-01-01T09:00', '2024-01-01T08:30'],\n    ['2024-01-01T17:00', '2024-01-01T16:30'],\n    ['2024-01-01T21:00', '2024-01-01T20:30']]),\n  ('missed alarm catch-up',\n   ['2024-01-01T09:00', 24, 2, -120, [], '2024-01-01T08:30', 48],\n   [['2024-01-01T09:00', '2024-01-01T08:30'], ['2024-01-02T09:00', '2024-01-02T07:00']]),\n  ('missed long before start',\n   ['2024-01-01T12:00', 24, 2, -1440, [], '2024-01-01T09:00', 48],\n   [['2024-01-01T12:00', '2024-01-01T09:00'], ['2024-01-02T12:00', '2024-01-01T12:00']]),\n  ('occurrence starting now',\n   ['2024-01-01T09:00', 24, 2, -10, [], '2024-01-01T09:00', 48],\n   [['2024-01-02T09:00', '2024-01-02T08:50']])],\n [('horizon edge with lead time',\n   ['2024-01-01T10:00', 1, 6, -60, [], '2024-01-01T08:00', 4],\n   [['2024-01-01T10:00', '2024-01-01T09:00'],\n    ['2024-01-01T11:00', '2024-01-01T10:00'],\n    ['2024-01-01T12:00', '2024-01-01T11:00'],\n    ['2024-01-01T13:00', '2024-01-01T12:00']]),\n  ('horizon exact',\n   ['2024-01-01T10:00', 2, 5, 0, [], '2024-01-01T08:00', 4],\n   [['2024-01-01T10:00', '2024-01-01T10:00'], ['2024-01-01T12:00', '2024-01-01T12:00']]),\n  ('acknowledged occurrence',\n   ['2024-01-01T09:00', 4, 4, -30, ['2024-01-01T13:00'], '2024-01-01T00:00', 48],\n   [['2024-01-01T09:00', '2024-01-01T08:30'],\n    ['2024-01-01T17:00', '2024-01-01T16:30'],\n    ['2024-01-01T21:00', '2024-01-01T20:30']]),\n  ('missed alarm catch-up',\n   ['2024-01-01T09:00', 24, 2, -120, [], '2024-01-01T08:30', 48],\n   [['2024-01-01T09:00', '2024-01-01T08:30'], ['2024-01-02T09:00', '2024-01-02T07:00']]),\n  ('missed long before start',\n   ['2024-01-01T12:00', 24, 2, -1440, [], '2024-01-01T09:00', 48],\n   [['2024-01-01T12:00', '2024-01-01T09:00'], ['2024-01-02T12:00', '2024-01-01T12:00']]),\n  ('occurrence starting now',\n   ['2024-01-01T09:00', 24, 2, -10, [], '2024-01-01T09:00', 48],\n   [['2024-01-02T09:00', '2024-01-02T08:50']]),\n  ('started occurrence dropped',\n   ['2024-01-01T09:00', 1, 4, -5, [], '2024-01-01T10:30', 4],\n   [['2024-01-01T11:00', '2024-01-01T10:55'], ['2024-01-01T12:00', '2024-01-01T11:55']])],\n [('acknowledged occurrence',\n   ['2024-01-01T09:00', 4, 4, -30, ['2024-01-01T13:00'], '2024-01-01T00:00', 48],\n   [['2024-01-01T09:00', '2024-01-01T08:30'],\n    ['2024-01-01T17:00', '2024-01-01T16:30'],\n    ['2024-01-01T21:00', '2024-01-01T20:30']]),\n  ('missed alarm catch-up',\n   ['2024-01-01T09:00', 24, 2, -120, [], '2024-01-01T08:30', 48],\n   [['2024-01-01T09:00', '2024-01-01T08:30'], ['2024-01-02T09:00', '2024-01-02T07:00']]),\n  ('missed long before start',\n   ['2024-01-01T12:00', 24, 2, -1440, [], '2024-01-01T09:00', 48],\n   [['2024-01-01T12:00', '2024-01-01T09:00'], ['2024-01-02T12:00', '2024-01-01T12:00']]),\n  ('occurrence starting now',\n   ['2024-01-01T09:00', 24, 2, -10, [], '2024-01-01T09:00', 48],\n   [['2024-01-02T09:00', '2024-01-02T08:50']]),\n  ('started occurrence dropped',\n   ['2024-01-01T09:00', 1, 4, -5, [], '2024-01-01T10:30', 4],\n   [['2024-01-01T11:00', '2024-01-01T10:55'], ['2024-01-01T12:00', '2024-01-01T11:55']]),\n  ('ack and catch-up mix',\n   ['2024-02-01T09:00', 3, 4, -240, ['2024-02-01T12:00'], '2024-02-01T08:00', 12],\n   [['2024-02-01T09:00', '2024-02-01T08:00'],\n    ['2024-02-01T15:00', '2024-02-01T11:00'],\n    ['2024-02-01T18:00', '2024-02-01T14:00']]),\n  ('zero trigger all future',\n   ['2024-03-01T06:00', 6, 3, 0, ['2024-03-01T06:00'], '2024-03-01T00:00', 24],\n   [['2024-03-01T12:00', '2024-03-01T12:00'], ['2024-03-01T18:00', '2024-03-01T18:00']])],\n [('missed long before start',\n   ['2024-01-01T12:00', 24, 2, -1440, [], '2024-01-01T09:00', 48],\n   [['2024-01-01T12:00', '2024-01-01T09:00'], ['2024-01-02T12:00', '2024-01-01T12:00']]),\n  ('occurrence starting now',\n   ['2024-01-01T09:00', 24, 2, -10, [], '2024-01-01T09:00', 48],\n   [['2024-01-02T09:00', '2024-01-02T08:50']]),\n  ('started occurrence dropped',\n   ['2024-01-01T09:00', 1, 4, -5, [], '2024-01-01T10:30', 4],\n   [['2024-01-01T11:00', '2024-01-01T10:55'], ['2024-01-01T12:00', '2024-01-01T11:55']]),\n  ('ack and catch-up mix',\n   ['2024-02-01T09:00', 3, 4, -240, ['2024-02-01T12:00'], '2024-02-01T08:00', 12],\n   [['2024-02-01T09:00', '2024-02-01T08:00'],\n    ['2024-02-01T15:00', '2024-02-01T11:00'],\n    ['2024-02-01T18:00', '2024-02-01T14:00']]),\n  ('zero trigger all future',\n   ['2024-03-01T06:00', 6, 3, 0, ['2024-03-01T06:00'], '2024-03-01T00:00', 24],\n   [['2024-03-01T12:00', '2024-03-01T12:00'], ['2024-03-01T18:00', '2024-03-01T18:00']]),\n  ('regression: negative trigger',\n   ['2024-01-01T09:00', 24, 3, -15, [], '2024-01-01T00:00', 72],\n   [['2024-01-01T09:00', '2024-01-01T08:45'],\n    ['2024-01-02T09:00', '2024-01-02T08:45'],\n    ['2024-01-03T09:00', '2024-01-03T08:45']]),\n  ('positive trigger',\n   ['2024-01-01T09:00', 24, 3, 10, [], '2024-01-01T00:00', 72],\n   [['2024-01-01T09:00', '2024-01-01T09:10'],\n    ['2024-01-02T09:00', '2024-01-02T09:10'],\n    ['2024-01-03T09:00', '2024-01-03T09:10']])],\n [('started occurrence dropped',\n   ['2024-01-01T09:00', 1, 4, -5, [], '2024-01-01T10:30', 4],\n   [['2024-01-01T11:00', '2024-01-01T10:55'], ['2024-01-01T12:00', '2024-01-01T11:55']]),\n  ('ack and catch-up mix',\n   ['2024-02-01T09:00', 3, 4, -240, ['2024-02-01T12:00'], '2024-02-01T08:00', 12],\n   [['2024-02-01T09:00', '2024-02-01T08:00'],\n    ['2024-02-01T15:00', '2024-02-01T11:00'],\n    ['2024-02-01T18:00', '2024-02-01T14:00']]),\n  ('zero trigger all future',\n   ['2024-03-01T06:00', 6, 3, 0, ['2024-03-01T06:00'], '2024-03-01T00:00', 24],\n   [['2024-03-01T12:00', '2024-03-01T12:00'], ['2024-03-01T18:00', '2024-03-01T18:00']]),\n  ('regression: negative trigger',\n   ['2024-01-01T09:00', 24, 3, -15, [], '2024-01-01T00:00', 72],\n   [['2024-01-01T09:00', '2024-01-01T08:45'],\n    ['2024-01-02T09:00', '2024-01-02T08:45'],\n    ['2024-01-03T09:00', '2024-01-03T08:45']]),\n  ('positive trigger',\n   ['2024-01-01T09:00', 24, 3, 10, [], '2024-01-01T00:00', 72],\n   [['2024-01-01T09:00', '2024-01-01T09:10'],\n    ['2024-01-02T09:00', '2024-01-02T09:10'],\n    ['2024-01-03T09:00', '2024-01-03T09:10']]),\n  ('horizon edge with lead time',\n   ['2024-01-01T10:00', 1, 6, -60, [], '2024-01-01T08:00', 4],\n   [['2024-01-01T10:00', '2024-01-01T09:00'],\n    ['2024-01-01T11:00', '2024-01-01T10:00'],\n    ['2024-01-01T12:00', '2024-01-01T11:00'],\n    ['2024-01-01T13:00', '2024-01-01T12:00']]),\n  ('horizon exact',\n   ['2024-01-01T10:00', 2, 5, 0, [], '2024-01-01T08:00', 4],\n   [['2024-01-01T10:00', '2024-01-01T10:00'], ['2024-01-01T12:00', '2024-01-01T12:00']]),\n  ('occurrence starting now',\n   ['2024-01-01T09:00', 24, 2, -10, [], '2024-01-01T09:00', 48],\n   [['2024-01-02T09:00', '2024-01-02T08:50']])]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-calendar-recurrence-rules-recurring-alarm-schedule-late-catchup","generated_at":"2026-09-29T14:49:23.254693+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Recurring calendar series are expanded into concrete instances for display, reminders and conflict checks.","root_cause":"Missed alarms are only caught up within a fixed 15 minute grace window.","sha256":"379f93605fbfa9147d1f52ac8a79cf1e4ce55fec3e217b689813f177d5b1d4ec","title":"Pending alarms for a recurring timed series: late catchup · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verified":true,"visibility":"public","verification":{"attempt":{"elapsed_ms":42.241,"exit_code":1,"observations":[{"actual":[["2024-01-01T09:00","2024-01-01T08:45"],["2024-01-02T09:00","2024-01-02T08:45"],["2024-01-03T09:00","2024-01-03T08:45"]],"check":"regression: negative trigger","expected":[["2024-01-01T09:00","2024-01-01T08:45"],["2024-01-02T09:00","2024-01-02T08:45"],["2024-01-03T09:00","2024-01-03T08:45"]],"passed":true},{"actual":[["2024-01-01T09:00","2024-01-01T09:10"],["2024-01-02T09:00","2024-01-02T09:10"],["2024-01-03T09:00","2024-01-03T09:10"]],"check":"positive trigger","expected":[["2024-01-01T09:00","2024-01-01T09:10"],["2024-01-02T09:00","2024-01-02T09:10"],["2024-01-03T09:00","2024-01-03T09:10"]],"passed":true},{"actual":[["2024-01-01T10:00","2024-01-01T09:00"],["2024-01-01T11:00","2024-01-01T10:00"],["2024-01-01T12:00","2024-01-01T11:00"],["2024-01-01T13:00","2024-01-01T12:00"]],"check":"horizon edge with lead time","expected":[["2024-01-01T10:00","2024-01-01T09:00"],["2024-01-01T11:00","2024-01-01T10:00"],["2024-01-01T12:00","2024-01-01T11:00"],["2024-01-01T13:00","2024-01-01T12:00"]],"passed":true},{"actual":[["2024-01-01T10:00","2024-01-01T10:00"],["2024-01-01T12:00","2024-01-01T12:00"]],"check":"horizon exact","expected":[["2024-01-01T10:00","2024-01-01T10:00"],["2024-01-01T12:00","2024-01-01T12:00"]],"passed":true},{"actual":[["2024-01-01T09:00","2024-01-01T08:30"],["2024-01-01T17:00","2024-01-01T16:30"],["2024-01-01T21:00","2024-01-01T20:30"]],"check":"acknowledged occurrence","expected":[["2024-01-01T09:00","2024-01-01T08:30"],["2024-01-01T17:00","2024-01-01T16:30"],["2024-01-01T21:00","2024-01-01T20:30"]],"passed":true},{"actual":[["2024-01-01T09:00","2024-01-01T08:30"],["2024-01-02T09:00","2024-01-02T07:00"]],"check":"missed alarm catch-up","expected":[["2024-01-01T09:00","2024-01-01T08:30"],["2024-01-02T09:00","2024-01-02T07:00"]],"passed":true},{"actual":[["2024-01-01T12:00","2024-01-01T09:00"],["2024-01-02T12:00","2024-01-01T12:00"]],"check":"missed long before start","expected":[["2024-01-01T12:00","2024-01-01T09:00"],["2024-01-02T12:00","2024-01-01T12:00"]],"passed":true},{"actual":[["2024-01-01T09:00","2024-01-01T09:00"],["2024-01-02T09:00","2024-01-02T08:50"]],"check":"occurrence starting now","expected":[["2024-01-02T09:00","2024-01-02T08:50"]],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: negative trigger\", \"actual\": [[\"2024-01-01T09:00\", \"2024-01-01T08:45\"], [\"2024-01-02T09:00\", \"2024-01-02T08:45\"], [\"2024-01-03T09:00\", \"2024-01-03T08:45\"]], \"expected\": [[\"2024-01-01T09:00\", \"2024-01-01T08:45\"], [\"2024-01-02T09:00\", \"2024-01-02T08:45\"], [\"2024-01-03T09:00\", \"2024-01-03T08:45\"]], \"passed\": true}, {\"check\": \"positive trigger\", \"actual\": [[\"2024-01-01T09:00\", \"2024-01-01T09:10\"], [\"2024-01-02T09:00\", \"2024-01-02T09:10\"], [\"2024-01-03T09:00\", \"2024-01-03T09:10\"]], \"expected\": [[\"2024-01-01T09:00\", \"2024-01-01T09:10\"], [\"2024-01-02T09:00\", \"2024-01-02T09:10\"], [\"2024-01-03T09:00\", \"2024-01-03T09:10\"]], \"passed\": true}, {\"check\": \"horizon edge with lead time\", \"actual\": [[\"2024-01-01T10:00\", \"2024-01-01T09:00\"], [\"2024-01-01T11:00\", \"2024-01-01T10:00\"], [\"2024-01-01T12:00\", \"2024-01-01T11:00\"], [\"2024-01-01T13:00\", \"2024-01-01T12:00\"]], \"expected\": [[\"2024-01-01T10:00\", \"2024-01-01T09:00\"], [\"2024-01-01T11:00\", \"2024-01-01T10:00\"], [\"2024-01-01T12:00\", \"2024-01-01T11:00\"], [\"2024-01-01T13:00\", \"2024-01-01T12:00\"]], \"passed\": true}, {\"check\": \"horizon exact\", \"actual\": [[\"2024-01-01T10:00\", \"2024-01-01T10:00\"], [\"2024-01-01T12:00\", \"2024-01-01T12:00\"]], \"expected\": [[\"2024-01-01T10:00\", \"2024-01-01T10:00\"], [\"2024-01-01T12:00\", \"2024-01-01T12:00\"]], \"passed\": true}, {\"check\": \"acknowledged occurrence\", \"actual\": [[\"2024-01-01T09:00\", \"2024-01-01T08:30\"], [\"2024-01-01T17:00\", \"2024-01-01T16:30\"], [\"2024-01-01T21:00\", \"2024-01-01T20:30\"]], \"expected\": [[\"2024-01-01T09:00\", \"2024-01-01T08:30\"], [\"2024-01-01T17:00\", \"2024-01-01T16:30\"], [\"2024-01-01T21:00\", \"2024-01-01T20:30\"]], \"passed\": true}, {\"check\": \"missed alarm catch-up\", \"actual\": [[\"2024-01-01T09:00\", \"2024-01-01T08:30\"], [\"2024-01-02T09:00\", \"2024-01-02T07:00\"]], \"expected\": [[\"2024-01-01T09:00\", \"2024-01-01T08:30\"], [\"2024-01-02T09:00\", \"2024-01-02T07:00\"]], \"passed\": true}, {\"check\": \"missed long before start\", \"actual\": [[\"2024-01-01T12:00\", \"2024-01-01T09:00\"], [\"2024-01-02T12:00\", \"2024-01-01T12:00\"]], \"expected\": [[\"2024-01-01T12:00\", \"2024-01-01T09:00\"], [\"2024-01-02T12:00\", \"2024-01-01T12:00\"]], \"passed\": true}, {\"check\": \"occurrence starting now\", \"actual\": [[\"2024-01-01T09:00\", \"2024-01-01T09:00\"], [\"2024-01-02T09:00\", \"2024-01-02T08:50\"]], \"expected\": [[\"2024-01-02T09:00\", \"2024-01-02T08:50\"]], \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.497,"exit_code":1,"observations":[{"actual":[["2024-01-01T09:00","2024-01-01T08:45"],["2024-01-02T09:00","2024-01-02T08:45"],["2024-01-03T09:00","2024-01-03T08:45"]],"check":"regression: negative trigger","expected":[["2024-01-01T09:00","2024-01-01T08:45"],["2024-01-02T09:00","2024-01-02T08:45"],["2024-01-03T09:00","2024-01-03T08:45"]],"passed":true},{"actual":[["2024-01-01T09:00","2024-01-01T09:10"],["2024-01-02T09:00","2024-01-02T09:10"],["2024-01-03T09:00","2024-01-03T09:10"]],"check":"positive trigger","expected":[["2024-01-01T09:00","2024-01-01T09:10"],["2024-01-02T09:00","2024-01-02T09:10"],["2024-01-03T09:00","2024-01-03T09:10"]],"passed":true},{"actual":[["2024-01-01T10:00","2024-01-01T09:00"],["2024-01-01T11:00","2024-01-01T10:00"],["2024-01-01T12:00","2024-01-01T11:00"],["2024-01-01T13:00","2024-01-01T12:00"]],"check":"horizon edge with lead time","expected":[["2024-01-01T10:00","2024-01-01T09:00"],["2024-01-01T11:00","2024-01-01T10:00"],["2024-01-01T12:00","2024-01-01T11:00"],["2024-01-01T13:00","2024-01-01T12:00"]],"passed":true},{"actual":[["2024-01-01T10:00","2024-01-01T10:00"],["2024-01-01T12:00","2024-01-01T12:00"]],"check":"horizon exact","expected":[["2024-01-01T10:00","2024-01-01T10:00"],["2024-01-01T12:00","2024-01-01T12:00"]],"passed":true},{"actual":[["2024-01-01T09:00","2024-01-01T08:30"],["2024-01-01T17:00","2024-01-01T16:30"],["2024-01-01T21:00","2024-01-01T20:30"]],"check":"acknowledged occurrence","expected":[["2024-01-01T09:00","2024-01-01T08:30"],["2024-01-01T17:00","2024-01-01T16:30"],["2024-01-01T21:00","2024-01-01T20:30"]],"passed":true},{"actual":[["2024-01-02T09:00","2024-01-02T07:00"]],"check":"missed alarm catch-up","expected":[["2024-01-01T09:00","2024-01-01T08:30"],["2024-01-02T09:00","2024-01-02T07:00"]],"passed":false},{"actual":[["2024-01-02T12:00","2024-01-01T12:00"]],"check":"missed long before start","expected":[["2024-01-01T12:00","2024-01-01T09:00"],["2024-01-02T12:00","2024-01-01T12:00"]],"passed":false},{"actual":[["2024-01-01T09:00","2024-01-01T09:00"],["2024-01-02T09:00","2024-01-02T08:50"]],"check":"occurrence starting now","expected":[["2024-01-02T09:00","2024-01-02T08:50"]],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: negative trigger\", \"actual\": [[\"2024-01-01T09:00\", \"2024-01-01T08:45\"], [\"2024-01-02T09:00\", \"2024-01-02T08:45\"], [\"2024-01-03T09:00\", \"2024-01-03T08:45\"]], \"expected\": [[\"2024-01-01T09:00\", \"2024-01-01T08:45\"], [\"2024-01-02T09:00\", \"2024-01-02T08:45\"], [\"2024-01-03T09:00\", \"2024-01-03T08:45\"]], \"passed\": true}, {\"check\": \"positive trigger\", \"actual\": [[\"2024-01-01T09:00\", \"2024-01-01T09:10\"], [\"2024-01-02T09:00\", \"2024-01-02T09:10\"], [\"2024-01-03T09:00\", \"2024-01-03T09:10\"]], \"expected\": [[\"2024-01-01T09:00\", \"2024-01-01T09:10\"], [\"2024-01-02T09:00\", \"2024-01-02T09:10\"], [\"2024-01-03T09:00\", \"2024-01-03T09:10\"]], \"passed\": true}, {\"check\": \"horizon edge with lead time\", \"actual\": [[\"2024-01-01T10:00\", \"2024-01-01T09:00\"], [\"2024-01-01T11:00\", \"2024-01-01T10:00\"], [\"2024-01-01T12:00\", \"2024-01-01T11:00\"], [\"2024-01-01T13:00\", \"2024-01-01T12:00\"]], \"expected\": [[\"2024-01-01T10:00\", \"2024-01-01T09:00\"], [\"2024-01-01T11:00\", \"2024-01-01T10:00\"], [\"2024-01-01T12:00\", \"2024-01-01T11:00\"], [\"2024-01-01T13:00\", \"2024-01-01T12:00\"]], \"passed\": true}, {\"check\": \"horizon exact\", \"actual\": [[\"2024-01-01T10:00\", \"2024-01-01T10:00\"], [\"2024-01-01T12:00\", \"2024-01-01T12:00\"]], \"expected\": [[\"2024-01-01T10:00\", \"2024-01-01T10:00\"], [\"2024-01-01T12:00\", \"2024-01-01T12:00\"]], \"passed\": true}, {\"check\": \"acknowledged occurrence\", \"actual\": [[\"2024-01-01T09:00\", \"2024-01-01T08:30\"], [\"2024-01-01T17:00\", \"2024-01-01T16:30\"], [\"2024-01-01T21:00\", \"2024-01-01T20:30\"]], \"expected\": [[\"2024-01-01T09:00\", \"2024-01-01T08:30\"], [\"2024-01-01T17:00\", \"2024-01-01T16:30\"], [\"2024-01-01T21:00\", \"2024-01-01T20:30\"]], \"passed\": true}, {\"check\": \"missed alarm catch-up\", \"actual\": [[\"2024-01-02T09:00\", \"2024-01-02T07:00\"]], \"expected\": [[\"2024-01-01T09:00\", \"2024-01-01T08:30\"], [\"2024-01-02T09:00\", \"2024-01-02T07:00\"]], \"passed\": false}, {\"check\": \"missed long before start\", \"actual\": [[\"2024-01-02T12:00\", \"2024-01-01T12:00\"]], \"expected\": [[\"2024-01-01T12:00\", \"2024-01-01T09:00\"], [\"2024-01-02T12:00\", \"2024-01-01T12:00\"]], \"passed\": false}, {\"check\": \"occurrence starting now\", \"actual\": [[\"2024-01-01T09:00\", \"2024-01-01T09:00\"], [\"2024-01-02T09:00\", \"2024-01-02T08:50\"]], \"expected\": [[\"2024-01-02T09:00\", \"2024-01-02T08:50\"]], \"passed\": false}], \"passed\": false}\n"}},"member_only":{"stages":["fixed"],"fields":["implementations.fixed","verification.fixed","harness","repair"],"note":"The verified repair, its recorded checks, the repair description, and the scoring harness are available to members."}}