{"abstract":"A rule written as \"freq=weekly\" is rejected as missing FREQ.","category":"Calendar recurrence rules","checks":7,"contract":"Parse \"NAME=VALUE;...\" rule text. Part names are case-insensitive; empty parts (a trailing \";\") are ignored; a part without \"=\" is malformed; any repeated part name is an error; FREQ is required. INTERVAL defaults to 1 and must be >= 1. BYDAY tokens are an optional signed 1-2 digit ordinal (explicit \"+\" allowed) followed by MO..SU; a present ordinal must satisfy 1 <= |n| <= 53. Errors are returned as {\"error\": message}; otherwise {\"freq\",\"interval\",\"byday\":[[n, day]],\"count\",\"until\"}.","evaluation_group":"w2-calendar-recurrence-rules-rrule-text-parser","failed_approach":"The partial repair `name.strip()` trims whitespace but still keeps the name case-sensitive.","family":"w2-calendar-recurrence-rules-rrule-text-parser-name-case","id":"FA-77216","implementations":{"attempt":{"sha256":"f16ff11439d422138b14b5bf7b5fddb486b9d35b822f956935e8c7d67ea1a796","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport re\nN = 1\nobservations = []\ndef solve(text):\n    parts = {}\n    for chunk in text.split(';'):\n        if not chunk:\n            continue\n        if '=' not in chunk:\n            return {'error': 'malformed'}\n        name, value = chunk.split('=', 1)\n        name = name.strip()\n        if name in parts:\n            return {'error': 'duplicate ' + name}\n        parts[name] = value\n    if 'FREQ' not in parts:\n        return {'error': 'missing FREQ'}\n    interval = int(parts.get('INTERVAL', '1'))\n    if interval < 1:\n        return {'error': 'bad INTERVAL'}\n    days = []\n    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):\n        m = re.fullmatch(r'([+-]?\\d{1,2})?(MO|TU|WE|TH|FR|SA|SU)', token)\n        if not m:\n            return {'error': 'bad BYDAY ' + token}\n        n = int(m.group(1)) if m.group(1) else 0\n        if m.group(1) and not 1 <= abs(n) <= 53:\n            return {'error': 'bad ordinal'}\n        days.append([n, m.group(2)])\n    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,\n            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression: lowercase names',\n   ['freq=WEEKLY;interval=2;byday=MO,WE'],\n   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),\n  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),\n  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),\n  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),\n  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),\n  ('plus ordinal',\n   ['FREQ=MONTHLY;BYDAY=+2TU'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),\n  ('two digit ordinal',\n   ['FREQ=YEARLY;BYDAY=20MO'],\n   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None})],\n [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),\n  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),\n  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),\n  ('plus ordinal',\n   ['FREQ=MONTHLY;BYDAY=+2TU'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),\n  ('two digit ordinal',\n   ['FREQ=YEARLY;BYDAY=20MO'],\n   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),\n  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),\n  ('negative ordinal',\n   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),\n  ('regression: lowercase names',\n   ['freq=WEEKLY;interval=2;byday=MO,WE'],\n   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None})],\n [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),\n  ('plus ordinal',\n   ['FREQ=MONTHLY;BYDAY=+2TU'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),\n  ('two digit ordinal',\n   ['FREQ=YEARLY;BYDAY=20MO'],\n   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),\n  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),\n  ('negative ordinal',\n   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),\n  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),\n  ('trailing semicolon',\n   ['FREQ=WEEKLY;UNTIL=20240301;'],\n   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),\n  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'})],\n [('two digit ordinal',\n   ['FREQ=YEARLY;BYDAY=20MO'],\n   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),\n  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),\n  ('negative ordinal',\n   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),\n  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),\n  ('trailing semicolon',\n   ['FREQ=WEEKLY;UNTIL=20240301;'],\n   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),\n  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),\n  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'})],\n [('negative ordinal',\n   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),\n  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),\n  ('trailing semicolon',\n   ['FREQ=WEEKLY;UNTIL=20240301;'],\n   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),\n  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),\n  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),\n  ('regression: lowercase names',\n   ['freq=WEEKLY;interval=2;byday=MO,WE'],\n   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),\n  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'})]]\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":"fb35dda8428e82423b398ab54e5e1572f22d77903cf34d7d53e3c01d479aa6da","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport re\nN = 1\nobservations = []\ndef solve(text):\n    parts = {}\n    for chunk in text.split(';'):\n        if not chunk:\n            continue\n        if '=' not in chunk:\n            return {'error': 'malformed'}\n        name, value = chunk.split('=', 1)\n        name = name\n        if name in parts:\n            return {'error': 'duplicate ' + name}\n        parts[name] = value\n    if 'FREQ' not in parts:\n        return {'error': 'missing FREQ'}\n    interval = int(parts.get('INTERVAL', '1'))\n    if interval < 1:\n        return {'error': 'bad INTERVAL'}\n    days = []\n    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):\n        m = re.fullmatch(r'([+-]?\\d{1,2})?(MO|TU|WE|TH|FR|SA|SU)', token)\n        if not m:\n            return {'error': 'bad BYDAY ' + token}\n        n = int(m.group(1)) if m.group(1) else 0\n        if m.group(1) and not 1 <= abs(n) <= 53:\n            return {'error': 'bad ordinal'}\n        days.append([n, m.group(2)])\n    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,\n            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression: lowercase names',\n   ['freq=WEEKLY;interval=2;byday=MO,WE'],\n   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),\n  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),\n  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),\n  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),\n  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),\n  ('plus ordinal',\n   ['FREQ=MONTHLY;BYDAY=+2TU'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),\n  ('two digit ordinal',\n   ['FREQ=YEARLY;BYDAY=20MO'],\n   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None})],\n [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),\n  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),\n  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),\n  ('plus ordinal',\n   ['FREQ=MONTHLY;BYDAY=+2TU'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),\n  ('two digit ordinal',\n   ['FREQ=YEARLY;BYDAY=20MO'],\n   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),\n  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),\n  ('negative ordinal',\n   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),\n  ('regression: lowercase names',\n   ['freq=WEEKLY;interval=2;byday=MO,WE'],\n   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None})],\n [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),\n  ('plus ordinal',\n   ['FREQ=MONTHLY;BYDAY=+2TU'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),\n  ('two digit ordinal',\n   ['FREQ=YEARLY;BYDAY=20MO'],\n   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),\n  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),\n  ('negative ordinal',\n   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),\n  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),\n  ('trailing semicolon',\n   ['FREQ=WEEKLY;UNTIL=20240301;'],\n   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),\n  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'})],\n [('two digit ordinal',\n   ['FREQ=YEARLY;BYDAY=20MO'],\n   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),\n  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),\n  ('negative ordinal',\n   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),\n  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),\n  ('trailing semicolon',\n   ['FREQ=WEEKLY;UNTIL=20240301;'],\n   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),\n  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),\n  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'})],\n [('negative ordinal',\n   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),\n  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),\n  ('trailing semicolon',\n   ['FREQ=WEEKLY;UNTIL=20240301;'],\n   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),\n  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),\n  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),\n  ('regression: lowercase names',\n   ['freq=WEEKLY;interval=2;byday=MO,WE'],\n   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),\n  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'})]]\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"},"fixed":{"sha256":"074a051995f1b112daad566f0e8e25b446bbb294850c4917a8606e7e235f5254","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport re\nN = 1\nobservations = []\ndef solve(text):\n    parts = {}\n    for chunk in text.split(';'):\n        if not chunk:\n            continue\n        if '=' not in chunk:\n            return {'error': 'malformed'}\n        name, value = chunk.split('=', 1)\n        name = name.upper()\n        if name in parts:\n            return {'error': 'duplicate ' + name}\n        parts[name] = value\n    if 'FREQ' not in parts:\n        return {'error': 'missing FREQ'}\n    interval = int(parts.get('INTERVAL', '1'))\n    if interval < 1:\n        return {'error': 'bad INTERVAL'}\n    days = []\n    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):\n        m = re.fullmatch(r'([+-]?\\d{1,2})?(MO|TU|WE|TH|FR|SA|SU)', token)\n        if not m:\n            return {'error': 'bad BYDAY ' + token}\n        n = int(m.group(1)) if m.group(1) else 0\n        if m.group(1) and not 1 <= abs(n) <= 53:\n            return {'error': 'bad ordinal'}\n        days.append([n, m.group(2)])\n    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,\n            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression: lowercase names',\n   ['freq=WEEKLY;interval=2;byday=MO,WE'],\n   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),\n  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),\n  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),\n  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),\n  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),\n  ('plus ordinal',\n   ['FREQ=MONTHLY;BYDAY=+2TU'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),\n  ('two digit ordinal',\n   ['FREQ=YEARLY;BYDAY=20MO'],\n   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None})],\n [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),\n  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),\n  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),\n  ('plus ordinal',\n   ['FREQ=MONTHLY;BYDAY=+2TU'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),\n  ('two digit ordinal',\n   ['FREQ=YEARLY;BYDAY=20MO'],\n   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),\n  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),\n  ('negative ordinal',\n   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),\n  ('regression: lowercase names',\n   ['freq=WEEKLY;interval=2;byday=MO,WE'],\n   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None})],\n [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),\n  ('plus ordinal',\n   ['FREQ=MONTHLY;BYDAY=+2TU'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),\n  ('two digit ordinal',\n   ['FREQ=YEARLY;BYDAY=20MO'],\n   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),\n  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),\n  ('negative ordinal',\n   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),\n  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),\n  ('trailing semicolon',\n   ['FREQ=WEEKLY;UNTIL=20240301;'],\n   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),\n  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'})],\n [('two digit ordinal',\n   ['FREQ=YEARLY;BYDAY=20MO'],\n   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),\n  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),\n  ('negative ordinal',\n   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),\n  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),\n  ('trailing semicolon',\n   ['FREQ=WEEKLY;UNTIL=20240301;'],\n   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),\n  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),\n  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'})],\n [('negative ordinal',\n   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],\n   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),\n  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),\n  ('trailing semicolon',\n   ['FREQ=WEEKLY;UNTIL=20240301;'],\n   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),\n  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),\n  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),\n  ('regression: lowercase names',\n   ['freq=WEEKLY;interval=2;byday=MO,WE'],\n   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),\n  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'})]]\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-rrule-text-parser-name-case","generated_at":"2026-09-29T14:49:23.600250+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.","repair":"At the name case decision use `name.upper()`, leaving the other decision sites of the model unchanged.","root_cause":"Part names are compared case-sensitively.","sha256":"d7b9b7ae7b60cc56c44a044d1faf967d365fc67d1df269224192b26bef4b296c","title":"Parsing and validating RRULE property text: name case · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":39.343,"exit_code":1,"observations":[{"actual":{"error":"missing FREQ"},"check":"regression: lowercase names","expected":{"byday":[[0,"MO"],[0,"WE"]],"count":null,"freq":"WEEKLY","interval":2,"until":null},"passed":false},{"actual":{"error":"duplicate COUNT"},"check":"duplicate count","expected":{"error":"duplicate COUNT"},"passed":true},{"actual":{"error":"duplicate COUNT"},"check":"identical duplicate","expected":{"error":"duplicate COUNT"},"passed":true},{"actual":{"error":"bad INTERVAL"},"check":"interval zero","expected":{"error":"bad INTERVAL"},"passed":true},{"actual":{"error":"bad INTERVAL"},"check":"interval negative","expected":{"error":"bad INTERVAL"},"passed":true},{"actual":{"byday":[[2,"TU"]],"count":null,"freq":"MONTHLY","interval":1,"until":null},"check":"plus ordinal","expected":{"byday":[[2,"TU"]],"count":null,"freq":"MONTHLY","interval":1,"until":null},"passed":true},{"actual":{"byday":[[20,"MO"]],"count":null,"freq":"YEARLY","interval":1,"until":null},"check":"two digit ordinal","expected":{"byday":[[20,"MO"]],"count":null,"freq":"YEARLY","interval":1,"until":null},"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: lowercase names\", \"actual\": {\"error\": \"missing FREQ\"}, \"expected\": {\"freq\": \"WEEKLY\", \"interval\": 2, \"byday\": [[0, \"MO\"], [0, \"WE\"]], \"count\": null, \"until\": null}, \"passed\": false}, {\"check\": \"duplicate count\", \"actual\": {\"error\": \"duplicate COUNT\"}, \"expected\": {\"error\": \"duplicate COUNT\"}, \"passed\": true}, {\"check\": \"identical duplicate\", \"actual\": {\"error\": \"duplicate COUNT\"}, \"expected\": {\"error\": \"duplicate COUNT\"}, \"passed\": true}, {\"check\": \"interval zero\", \"actual\": {\"error\": \"bad INTERVAL\"}, \"expected\": {\"error\": \"bad INTERVAL\"}, \"passed\": true}, {\"check\": \"interval negative\", \"actual\": {\"error\": \"bad INTERVAL\"}, \"expected\": {\"error\": \"bad INTERVAL\"}, \"passed\": true}, {\"check\": \"plus ordinal\", \"actual\": {\"freq\": \"MONTHLY\", \"interval\": 1, \"byday\": [[2, \"TU\"]], \"count\": null, \"until\": null}, \"expected\": {\"freq\": \"MONTHLY\", \"interval\": 1, \"byday\": [[2, \"TU\"]], \"count\": null, \"until\": null}, \"passed\": true}, {\"check\": \"two digit ordinal\", \"actual\": {\"freq\": \"YEARLY\", \"interval\": 1, \"byday\": [[20, \"MO\"]], \"count\": null, \"until\": null}, \"expected\": {\"freq\": \"YEARLY\", \"interval\": 1, \"byday\": [[20, \"MO\"]], \"count\": null, \"until\": null}, \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.73,"exit_code":1,"observations":[{"actual":{"error":"missing FREQ"},"check":"regression: lowercase names","expected":{"byday":[[0,"MO"],[0,"WE"]],"count":null,"freq":"WEEKLY","interval":2,"until":null},"passed":false},{"actual":{"error":"duplicate COUNT"},"check":"duplicate count","expected":{"error":"duplicate COUNT"},"passed":true},{"actual":{"error":"duplicate COUNT"},"check":"identical duplicate","expected":{"error":"duplicate COUNT"},"passed":true},{"actual":{"error":"bad INTERVAL"},"check":"interval zero","expected":{"error":"bad INTERVAL"},"passed":true},{"actual":{"error":"bad INTERVAL"},"check":"interval negative","expected":{"error":"bad INTERVAL"},"passed":true},{"actual":{"byday":[[2,"TU"]],"count":null,"freq":"MONTHLY","interval":1,"until":null},"check":"plus ordinal","expected":{"byday":[[2,"TU"]],"count":null,"freq":"MONTHLY","interval":1,"until":null},"passed":true},{"actual":{"byday":[[20,"MO"]],"count":null,"freq":"YEARLY","interval":1,"until":null},"check":"two digit ordinal","expected":{"byday":[[20,"MO"]],"count":null,"freq":"YEARLY","interval":1,"until":null},"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: lowercase names\", \"actual\": {\"error\": \"missing FREQ\"}, \"expected\": {\"freq\": \"WEEKLY\", \"interval\": 2, \"byday\": [[0, \"MO\"], [0, \"WE\"]], \"count\": null, \"until\": null}, \"passed\": false}, {\"check\": \"duplicate count\", \"actual\": {\"error\": \"duplicate COUNT\"}, \"expected\": {\"error\": \"duplicate COUNT\"}, \"passed\": true}, {\"check\": \"identical duplicate\", \"actual\": {\"error\": \"duplicate COUNT\"}, \"expected\": {\"error\": \"duplicate COUNT\"}, \"passed\": true}, {\"check\": \"interval zero\", \"actual\": {\"error\": \"bad INTERVAL\"}, \"expected\": {\"error\": \"bad INTERVAL\"}, \"passed\": true}, {\"check\": \"interval negative\", \"actual\": {\"error\": \"bad INTERVAL\"}, \"expected\": {\"error\": \"bad INTERVAL\"}, \"passed\": true}, {\"check\": \"plus ordinal\", \"actual\": {\"freq\": \"MONTHLY\", \"interval\": 1, \"byday\": [[2, \"TU\"]], \"count\": null, \"until\": null}, \"expected\": {\"freq\": \"MONTHLY\", \"interval\": 1, \"byday\": [[2, \"TU\"]], \"count\": null, \"until\": null}, \"passed\": true}, {\"check\": \"two digit ordinal\", \"actual\": {\"freq\": \"YEARLY\", \"interval\": 1, \"byday\": [[20, \"MO\"]], \"count\": null, \"until\": null}, \"expected\": {\"freq\": \"YEARLY\", \"interval\": 1, \"byday\": [[20, \"MO\"]], \"count\": null, \"until\": null}, \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":39.557,"exit_code":0,"observations":[{"actual":{"byday":[[0,"MO"],[0,"WE"]],"count":null,"freq":"WEEKLY","interval":2,"until":null},"check":"regression: lowercase names","expected":{"byday":[[0,"MO"],[0,"WE"]],"count":null,"freq":"WEEKLY","interval":2,"until":null},"passed":true},{"actual":{"error":"duplicate COUNT"},"check":"duplicate count","expected":{"error":"duplicate COUNT"},"passed":true},{"actual":{"error":"duplicate COUNT"},"check":"identical duplicate","expected":{"error":"duplicate COUNT"},"passed":true},{"actual":{"error":"bad INTERVAL"},"check":"interval zero","expected":{"error":"bad INTERVAL"},"passed":true},{"actual":{"error":"bad INTERVAL"},"check":"interval negative","expected":{"error":"bad INTERVAL"},"passed":true},{"actual":{"byday":[[2,"TU"]],"count":null,"freq":"MONTHLY","interval":1,"until":null},"check":"plus ordinal","expected":{"byday":[[2,"TU"]],"count":null,"freq":"MONTHLY","interval":1,"until":null},"passed":true},{"actual":{"byday":[[20,"MO"]],"count":null,"freq":"YEARLY","interval":1,"until":null},"check":"two digit ordinal","expected":{"byday":[[20,"MO"]],"count":null,"freq":"YEARLY","interval":1,"until":null},"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: lowercase names\", \"actual\": {\"freq\": \"WEEKLY\", \"interval\": 2, \"byday\": [[0, \"MO\"], [0, \"WE\"]], \"count\": null, \"until\": null}, \"expected\": {\"freq\": \"WEEKLY\", \"interval\": 2, \"byday\": [[0, \"MO\"], [0, \"WE\"]], \"count\": null, \"until\": null}, \"passed\": true}, {\"check\": \"duplicate count\", \"actual\": {\"error\": \"duplicate COUNT\"}, \"expected\": {\"error\": \"duplicate COUNT\"}, \"passed\": true}, {\"check\": \"identical duplicate\", \"actual\": {\"error\": \"duplicate COUNT\"}, \"expected\": {\"error\": \"duplicate COUNT\"}, \"passed\": true}, {\"check\": \"interval zero\", \"actual\": {\"error\": \"bad INTERVAL\"}, \"expected\": {\"error\": \"bad INTERVAL\"}, \"passed\": true}, {\"check\": \"interval negative\", \"actual\": {\"error\": \"bad INTERVAL\"}, \"expected\": {\"error\": \"bad INTERVAL\"}, \"passed\": true}, {\"check\": \"plus ordinal\", \"actual\": {\"freq\": \"MONTHLY\", \"interval\": 1, \"byday\": [[2, \"TU\"]], \"count\": null, \"until\": null}, \"expected\": {\"freq\": \"MONTHLY\", \"interval\": 1, \"byday\": [[2, \"TU\"]], \"count\": null, \"until\": null}, \"passed\": true}, {\"check\": \"two digit ordinal\", \"actual\": {\"freq\": \"YEARLY\", \"interval\": 1, \"byday\": [[20, \"MO\"]], \"count\": null, \"until\": null}, \"expected\": {\"freq\": \"YEARLY\", \"interval\": 1, \"byday\": [[20, \"MO\"]], \"count\": null, \"until\": null}, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}