{"abstract":"Changes within the calendar year are credited with too much earned exposure.","category":"Insurance premium rating","checks":8,"contract":"Input changes [[month offset from calendar-year start, change per mille]] in order. Annual policies written uniformly; the share of calendar-year earned exposure written after offset d=m/12 is (1-d)^2/2 for 0<=d<1, 1-(1+d)^2/2 for -1<d<0, 0 for d>=1 and 1 for d<=-1. Levels are cumulative products. OLF = current level / earned-weighted average level, returned *1000 rounded half-up.","evaluation_group":"w2-insurance_premium_rating-onlevel-parallelogram","failed_approach":"Dropping the one-half doubles the triangle.","family":"w2-insurance_premium_rating-onlevel-parallelogram-current-year-area","id":"FA-63016","implementations":{"attempt":{"sha256":"498386aa8a80efd9dc9583d3fc433dcbdaae301b1bee1be23a35b0e15b105198","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nfrom fractions import Fraction\nN = 1\nobservations = []\ndef solve(x):\n    def after(m):\n        d=Fraction(m,12)\n        if d>=1: return Fraction(0)\n        if d<=-1: return Fraction(1)\n        if d>=0: return (1-d)**2\n        return 1-(1+d)**2/2\n    level=Fraction(1); levels=[level]\n    for m,c in x['changes']:\n        level*=1+Fraction(c,1000); levels.append(level)\n    avg=Fraction(0)\n    prev=Fraction(1)\n    for i,(m,c) in enumerate(x['changes']):\n        a=after(m)\n        avg+=levels[i]*(prev-a)\n        prev=a\n    avg+=levels[-1]*prev\n    return math.floor(levels[-1]/avg*1000+Fraction(1,2))\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['single mid-year change', {'changes': [[3, 100]]}, 1070], ['change in prior year', {'changes': [[-7, 45]]}, 1004], ['two changes straddling', {'changes': [[-8, 45], [2, -50]]}, 969], ['three changes', {'changes': [[-9, 30], [3, 100], [8, -50]]}, 1020], ['change at year start', {'changes': [[0, 45]]}, 1022], ['change long before period', {'changes': [[-14, -50], [3, 100]]}, 1070], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[10, -80]]}, 921]], [['single mid-year change', {'changes': [[5, 60]]}, 1049], ['change in prior year', {'changes': [[-8, 30]]}, 1002], ['two changes straddling', {'changes': [[-6, 80], [6, 60]]}, 1062], ['three changes', {'changes': [[-6, 30], [4, 30], [7, 100]]}, 1120], ['change at year start', {'changes': [[0, 80]]}, 1038], ['change long before period', {'changes': [[-14, 100], [4, -50]]}, 961], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[6, -80]]}, 929]], [['single mid-year change', {'changes': [[8, 60]]}, 1056], ['change in prior year', {'changes': [[-3, -50]]}, 985], ['two changes straddling', {'changes': [[-7, 100], [2, 100]]}, 1071], ['three changes', {'changes': [[-11, -50], [0, -50], [10, 100]]}, 1070], ['change at year start', {'changes': [[0, 100]]}, 1048], ['change long before period', {'changes': [[-14, -50], [4, 30]]}, 1023], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[4, -80]]}, 937]], [['single mid-year change', {'changes': [[4, 80]]}, 1061], ['change in prior year', {'changes': [[-9, 60]]}, 1002], ['two changes straddling', {'changes': [[-4, 80], [8, 100]]}, 1112], ['three changes', {'changes': [[-2, 30], [2, 60], [8, 60]]}, 1108], ['change at year start', {'changes': [[0, 45]]}, 1022], ['change long before period', {'changes': [[-14, 30], [4, 60]]}, 1046], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[2, -80]]}, 946]], [['single mid-year change', {'changes': [[9, -50]]}, 951], ['change in prior year', {'changes': [[-5, -50]]}, 991], ['two changes straddling', {'changes': [[-8, 80], [5, -50]]}, 962], ['three changes', {'changes': [[-3, 80], [5, 30], [7, 60]]}, 1103], ['change at year start', {'changes': [[0, 100]]}, 1048], ['change long before period', {'changes': [[-14, 45], [4, 60]]}, 1046], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[4, -80]]}, 937]]]\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":"a317aabae09e8db9451d8d3e268a07408390b3ae2282ead77addf4964ce4ef93","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nfrom fractions import Fraction\nN = 1\nobservations = []\ndef solve(x):\n    def after(m):\n        d=Fraction(m,12)\n        if d>=1: return Fraction(0)\n        if d<=-1: return Fraction(1)\n        if d>=0: return (1-d)\n        return 1-(1+d)**2/2\n    level=Fraction(1); levels=[level]\n    for m,c in x['changes']:\n        level*=1+Fraction(c,1000); levels.append(level)\n    avg=Fraction(0)\n    prev=Fraction(1)\n    for i,(m,c) in enumerate(x['changes']):\n        a=after(m)\n        avg+=levels[i]*(prev-a)\n        prev=a\n    avg+=levels[-1]*prev\n    return math.floor(levels[-1]/avg*1000+Fraction(1,2))\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['single mid-year change', {'changes': [[3, 100]]}, 1070], ['change in prior year', {'changes': [[-7, 45]]}, 1004], ['two changes straddling', {'changes': [[-8, 45], [2, -50]]}, 969], ['three changes', {'changes': [[-9, 30], [3, 100], [8, -50]]}, 1020], ['change at year start', {'changes': [[0, 45]]}, 1022], ['change long before period', {'changes': [[-14, -50], [3, 100]]}, 1070], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[10, -80]]}, 921]], [['single mid-year change', {'changes': [[5, 60]]}, 1049], ['change in prior year', {'changes': [[-8, 30]]}, 1002], ['two changes straddling', {'changes': [[-6, 80], [6, 60]]}, 1062], ['three changes', {'changes': [[-6, 30], [4, 30], [7, 100]]}, 1120], ['change at year start', {'changes': [[0, 80]]}, 1038], ['change long before period', {'changes': [[-14, 100], [4, -50]]}, 961], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[6, -80]]}, 929]], [['single mid-year change', {'changes': [[8, 60]]}, 1056], ['change in prior year', {'changes': [[-3, -50]]}, 985], ['two changes straddling', {'changes': [[-7, 100], [2, 100]]}, 1071], ['three changes', {'changes': [[-11, -50], [0, -50], [10, 100]]}, 1070], ['change at year start', {'changes': [[0, 100]]}, 1048], ['change long before period', {'changes': [[-14, -50], [4, 30]]}, 1023], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[4, -80]]}, 937]], [['single mid-year change', {'changes': [[4, 80]]}, 1061], ['change in prior year', {'changes': [[-9, 60]]}, 1002], ['two changes straddling', {'changes': [[-4, 80], [8, 100]]}, 1112], ['three changes', {'changes': [[-2, 30], [2, 60], [8, 60]]}, 1108], ['change at year start', {'changes': [[0, 45]]}, 1022], ['change long before period', {'changes': [[-14, 30], [4, 60]]}, 1046], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[2, -80]]}, 946]], [['single mid-year change', {'changes': [[9, -50]]}, 951], ['change in prior year', {'changes': [[-5, -50]]}, 991], ['two changes straddling', {'changes': [[-8, 80], [5, -50]]}, 962], ['three changes', {'changes': [[-3, 80], [5, 30], [7, 60]]}, 1103], ['change at year start', {'changes': [[0, 100]]}, 1048], ['change long before period', {'changes': [[-14, 45], [4, 60]]}, 1046], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[4, -80]]}, 937]]]\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":"955ae0b8d1af18c2c45ee5114cda871716060f5573910736e91a1fcc01c25b41","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nfrom fractions import Fraction\nN = 1\nobservations = []\ndef solve(x):\n    def after(m):\n        d=Fraction(m,12)\n        if d>=1: return Fraction(0)\n        if d<=-1: return Fraction(1)\n        if d>=0: return (1-d)**2/2\n        return 1-(1+d)**2/2\n    level=Fraction(1); levels=[level]\n    for m,c in x['changes']:\n        level*=1+Fraction(c,1000); levels.append(level)\n    avg=Fraction(0)\n    prev=Fraction(1)\n    for i,(m,c) in enumerate(x['changes']):\n        a=after(m)\n        avg+=levels[i]*(prev-a)\n        prev=a\n    avg+=levels[-1]*prev\n    return math.floor(levels[-1]/avg*1000+Fraction(1,2))\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['single mid-year change', {'changes': [[3, 100]]}, 1070], ['change in prior year', {'changes': [[-7, 45]]}, 1004], ['two changes straddling', {'changes': [[-8, 45], [2, -50]]}, 969], ['three changes', {'changes': [[-9, 30], [3, 100], [8, -50]]}, 1020], ['change at year start', {'changes': [[0, 45]]}, 1022], ['change long before period', {'changes': [[-14, -50], [3, 100]]}, 1070], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[10, -80]]}, 921]], [['single mid-year change', {'changes': [[5, 60]]}, 1049], ['change in prior year', {'changes': [[-8, 30]]}, 1002], ['two changes straddling', {'changes': [[-6, 80], [6, 60]]}, 1062], ['three changes', {'changes': [[-6, 30], [4, 30], [7, 100]]}, 1120], ['change at year start', {'changes': [[0, 80]]}, 1038], ['change long before period', {'changes': [[-14, 100], [4, -50]]}, 961], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[6, -80]]}, 929]], [['single mid-year change', {'changes': [[8, 60]]}, 1056], ['change in prior year', {'changes': [[-3, -50]]}, 985], ['two changes straddling', {'changes': [[-7, 100], [2, 100]]}, 1071], ['three changes', {'changes': [[-11, -50], [0, -50], [10, 100]]}, 1070], ['change at year start', {'changes': [[0, 100]]}, 1048], ['change long before period', {'changes': [[-14, -50], [4, 30]]}, 1023], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[4, -80]]}, 937]], [['single mid-year change', {'changes': [[4, 80]]}, 1061], ['change in prior year', {'changes': [[-9, 60]]}, 1002], ['two changes straddling', {'changes': [[-4, 80], [8, 100]]}, 1112], ['three changes', {'changes': [[-2, 30], [2, 60], [8, 60]]}, 1108], ['change at year start', {'changes': [[0, 45]]}, 1022], ['change long before period', {'changes': [[-14, 30], [4, 60]]}, 1046], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[2, -80]]}, 946]], [['single mid-year change', {'changes': [[9, -50]]}, 951], ['change in prior year', {'changes': [[-5, -50]]}, 991], ['two changes straddling', {'changes': [[-8, 80], [5, -50]]}, 962], ['three changes', {'changes': [[-3, 80], [5, 30], [7, 60]]}, 1103], ['change at year start', {'changes': [[0, 100]]}, 1048], ['change long before period', {'changes': [[-14, 45], [4, 60]]}, 1046], ['no changes', {'changes': []}, 1000], ['rate decrease', {'changes': [[4, -80]]}, 937]]]\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":"A deterministic bounded teaching model of a stipulated toy rating contract. Amounts are integer cents and factors exact rationals; it makes no claim of conformance with any filed rating plan, bureau manual or jurisdiction. 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-insurance_premium_rating-onlevel-parallelogram-current-year-area","generated_at":"2026-09-29T14:47:10.208923+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"On-level factors restate historical earned premium at current rates before comparing to losses.","repair":"Use the triangle (1-d)^2/2.","root_cause":"The area after a mid-year change is taken as the written fraction 1-d.","sha256":"edb5b694f800e819b4f32c28afbee61bd5fd31d08260da2185c3b1ea11ab5296","title":"Parallelogram on-level factor: Current-year change area is not triangular · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":42.24,"exit_code":1,"observations":[{"actual":1041,"check":"single mid-year change","expected":1070,"passed":false},{"actual":1004,"check":"change in prior year","expected":1004,"passed":true},{"actual":987,"check":"two changes straddling","expected":969,"passed":false},{"actual":996,"check":"three changes","expected":1020,"passed":false},{"actual":1000,"check":"change at year start","expected":1022,"passed":false},{"actual":1041,"check":"change long before period","expected":1070,"passed":false},{"actual":1000,"check":"no changes","expected":1000,"passed":true},{"actual":922,"check":"rate decrease","expected":921,"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"single mid-year change\", \"actual\": 1041, \"expected\": 1070, \"passed\": false}, {\"check\": \"change in prior year\", \"actual\": 1004, \"expected\": 1004, \"passed\": true}, {\"check\": \"two changes straddling\", \"actual\": 987, \"expected\": 969, \"passed\": false}, {\"check\": \"three changes\", \"actual\": 996, \"expected\": 1020, \"passed\": false}, {\"check\": \"change at year start\", \"actual\": 1000, \"expected\": 1022, \"passed\": false}, {\"check\": \"change long before period\", \"actual\": 1041, \"expected\": 1070, \"passed\": false}, {\"check\": \"no changes\", \"actual\": 1000, \"expected\": 1000, \"passed\": true}, {\"check\": \"rate decrease\", \"actual\": 922, \"expected\": 921, \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":44.014,"exit_code":1,"observations":[{"actual":1023,"check":"single mid-year change","expected":1070,"passed":false},{"actual":1004,"check":"change in prior year","expected":1004,"passed":true},{"actual":994,"check":"two changes straddling","expected":969,"passed":false},{"actual":990,"check":"three changes","expected":1020,"passed":false},{"actual":1000,"check":"change at year start","expected":1022,"passed":false},{"actual":1023,"check":"change long before period","expected":1070,"passed":false},{"actual":1000,"check":"no changes","expected":1000,"passed":true},{"actual":932,"check":"rate decrease","expected":921,"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"single mid-year change\", \"actual\": 1023, \"expected\": 1070, \"passed\": false}, {\"check\": \"change in prior year\", \"actual\": 1004, \"expected\": 1004, \"passed\": true}, {\"check\": \"two changes straddling\", \"actual\": 994, \"expected\": 969, \"passed\": false}, {\"check\": \"three changes\", \"actual\": 990, \"expected\": 1020, \"passed\": false}, {\"check\": \"change at year start\", \"actual\": 1000, \"expected\": 1022, \"passed\": false}, {\"check\": \"change long before period\", \"actual\": 1023, \"expected\": 1070, \"passed\": false}, {\"check\": \"no changes\", \"actual\": 1000, \"expected\": 1000, \"passed\": true}, {\"check\": \"rate decrease\", \"actual\": 932, \"expected\": 921, \"passed\": false}], \"passed\": false}\n"},"fixed":{"elapsed_ms":44.204,"exit_code":0,"observations":[{"actual":1070,"check":"single mid-year change","expected":1070,"passed":true},{"actual":1004,"check":"change in prior year","expected":1004,"passed":true},{"actual":969,"check":"two changes straddling","expected":969,"passed":true},{"actual":1020,"check":"three changes","expected":1020,"passed":true},{"actual":1022,"check":"change at year start","expected":1022,"passed":true},{"actual":1070,"check":"change long before period","expected":1070,"passed":true},{"actual":1000,"check":"no changes","expected":1000,"passed":true},{"actual":921,"check":"rate decrease","expected":921,"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"single mid-year change\", \"actual\": 1070, \"expected\": 1070, \"passed\": true}, {\"check\": \"change in prior year\", \"actual\": 1004, \"expected\": 1004, \"passed\": true}, {\"check\": \"two changes straddling\", \"actual\": 969, \"expected\": 969, \"passed\": true}, {\"check\": \"three changes\", \"actual\": 1020, \"expected\": 1020, \"passed\": true}, {\"check\": \"change at year start\", \"actual\": 1022, \"expected\": 1022, \"passed\": true}, {\"check\": \"change long before period\", \"actual\": 1070, \"expected\": 1070, \"passed\": true}, {\"check\": \"no changes\", \"actual\": 1000, \"expected\": 1000, \"passed\": true}, {\"check\": \"rate decrease\", \"actual\": 921, \"expected\": 921, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}