FA-63226 / Insurance premium rating / Open access
Retrospective rating adjustment: Minimum retro premium is not applied · case 01
Loss-free insureds pay less than the plan minimum.
ROOT CAUSE
Only the maximum bound is enforced.
VERIFIED REPAIR
Clamp to [min, max].
Unsuccessful approach: Skipping the minimum when there are no limited losses misses exactly the loss-free case.
Case contract
Input standard premium, basic, lcf, tax (x1000), min and max (per mille of standard), loss_limit, claims (negative = recovery). max<min -> 'invalid bounds'. Limited losses = max(0, sum(min(claim, limit))). Retro = (standard*basic + limited*lcf)*tax, bounded by [standard*min, standard*max] (bounds already include tax), rounded half-up. Return [limited, retro].
Why this case matters
Retrospective plans settle premium after losses, so each conversion factor and bound has to sit at the right step.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
sp=x['standard']
if x['max']<x['min']: return 'invalid bounds'
lim=max(0,sum(min(c,x['loss_limit']) for c in x['claims']))
basic=Fraction(sp*x['basic'],1000)
retro=(basic+Fraction(lim*x['lcf'],1000))*Fraction(x['tax'],1000)
lo=Fraction(sp*x['min'],1000); hi=Fraction(sp*x['max'],1000)
retro=min(hi,retro)
return [lim, math.floor(retro+Fraction(1,2))]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['moderate losses between bounds', {'standard': 1208187, 'basic': 250, 'lcf': 1100, 'tax': 1030, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [65251, 117766, 199866, 72604]}, [455487, 827175]], ['large claim limited', {'standard': 1536795, 'basic': 250, 'lcf': 1100, 'tax': 1050, 'min': 600, 'max': 3000, 'loss_limit': 5000000, 'claims': [7899385, 85219]}, [5085219, 4610385]], ['maximum binds', {'standard': 576969, 'basic': 250, 'lcf': 1100, 'tax': 1030, 'min': 500, 'max': 1200, 'loss_limit': 5000000, 'claims': [3887820, 3676391, 3519603, 3011895]}, [14095709, 692363]], ['no losses minimum binds', {'standard': 783317, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 500, 'max': 1400, 'loss_limit': 5000000, 'claims': []}, [0, 391659]], ['subrogation recovery offsets', {'standard': 1402360, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [299401, -71949]}, [227452, 581085]], ['net recovery floors at zero', {'standard': 1970882, 'basic': 200, 'lcf': 1150, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-13900]}, [0, 591265]], ['inverted bounds rejected', {'standard': 857821, 'basic': 200, 'lcf': 1150, 'tax': 1030, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 1032758, 'basic': 250, 'lcf': 1200, 'tax': 1030, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 929482]], ['near-minimum losses', {'standard': 1037917, 'basic': 250, 'lcf': 1200, 'tax': 1030, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [196003]}, [196003, 509523]]], [['moderate losses between bounds', {'standard': 559811, 'basic': 250, 'lcf': 1150, 'tax': 1030, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [168808, 170340, 188681, 153930]}, [681759, 951695]], ['large claim limited', {'standard': 1398667, 'basic': 200, 'lcf': 1150, 'tax': 1030, 'min': 500, 'max': 3000, 'loss_limit': 5000000, 'claims': [8563900, 72244]}, [5072244, 4196001]], ['maximum binds', {'standard': 1860838, 'basic': 250, 'lcf': 1100, 'tax': 1050, 'min': 600, 'max': 1200, 'loss_limit': 5000000, 'claims': [3974702, 2021857, 3323996, 2741110]}, [12061665, 2233006]], ['no losses minimum binds', {'standard': 1054836, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 500, 'max': 1400, 'loss_limit': 5000000, 'claims': []}, [0, 527418]], ['subrogation recovery offsets', {'standard': 572933, 'basic': 250, 'lcf': 1150, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [215865, -67794]}, [148071, 322920]], ['net recovery floors at zero', {'standard': 1415569, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-23951]}, [0, 424671]], ['inverted bounds rejected', {'standard': 1885857, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 1658903, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 1493013]], ['near-minimum losses', {'standard': 1831216, 'basic': 250, 'lcf': 1150, 'tax': 1030, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [255597]}, [255597, 824047]]], [['moderate losses between bounds', {'standard': 1953166, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [130486, 146045, 106267, 80838]}, [463636, 970005]], ['large claim limited', {'standard': 1375996, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 600, 'max': 3000, 'loss_limit': 5000000, 'claims': [8850428, 26063]}, [5026063, 4127988]], ['maximum binds', {'standard': 1822101, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 600, 'max': 1200, 'loss_limit': 5000000, 'claims': [3010425, 2467545, 2177771, 3447891]}, [11103632, 2186521]], ['no losses minimum binds', {'standard': 1516833, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 500, 'max': 1400, 'loss_limit': 5000000, 'claims': []}, [0, 758417]], ['subrogation recovery offsets', {'standard': 714829, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [292326, -101272]}, [191054, 370781]], ['net recovery floors at zero', {'standard': 1501098, 'basic': 200, 'lcf': 1100, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-22616]}, [0, 450329]], ['inverted bounds rejected', {'standard': 696781, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 802028, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 721825]], ['near-minimum losses', {'standard': 715359, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [161153]}, [161153, 346549]]], [['moderate losses between bounds', {'standard': 714988, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [147807, 50783, 101639, 147624]}, [447853, 714442]], ['large claim limited', {'standard': 1075364, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 600, 'max': 3000, 'loss_limit': 5000000, 'claims': [6621396, 51697]}, [5051697, 3226092]], ['maximum binds', {'standard': 636493, 'basic': 250, 'lcf': 1200, 'tax': 1050, 'min': 500, 'max': 1200, 'loss_limit': 5000000, 'claims': [3206066, 2811387, 2370852, 2596520]}, [10984825, 763792]], ['no losses minimum binds', {'standard': 1974481, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 500, 'max': 1600, 'loss_limit': 5000000, 'claims': []}, [0, 987241]], ['subrogation recovery offsets', {'standard': 1092045, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [210597, -95806]}, [114791, 366843]], ['net recovery floors at zero', {'standard': 1088467, 'basic': 250, 'lcf': 1200, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-13789]}, [0, 326540]], ['inverted bounds rejected', {'standard': 1508678, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 811592, 'basic': 250, 'lcf': 1200, 'tax': 1050, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 730433]], ['near-minimum losses', {'standard': 1513685, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [237641]}, [237641, 681158]]], [['moderate losses between bounds', {'standard': 1863348, 'basic': 250, 'lcf': 1200, 'tax': 1050, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [182396, 119506, 129126, 64521]}, [495549, 1113521]], ['large claim limited', {'standard': 1794820, 'basic': 200, 'lcf': 1100, 'tax': 1030, 'min': 500, 'max': 3000, 'loss_limit': 5000000, 'claims': [6997029, 30223]}, [5030223, 5384460]], ['maximum binds', {'standard': 1446879, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 500, 'max': 1200, 'loss_limit': 5000000, 'claims': [3226070, 2149089, 2381869, 2566788]}, [10323816, 1736255]], ['no losses minimum binds', {'standard': 1111989, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 500, 'max': 1400, 'loss_limit': 5000000, 'claims': []}, [0, 555995]], ['subrogation recovery offsets', {'standard': 930668, 'basic': 250, 'lcf': 1150, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [215001, -125166]}, [89835, 346057]], ['net recovery floors at zero', {'standard': 790663, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-24524]}, [0, 237199]], ['inverted bounds rejected', {'standard': 901935, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 802066, 'basic': 250, 'lcf': 1150, 'tax': 1050, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 721859]], ['near-minimum losses', {'standard': 1352189, 'basic': 250, 'lcf': 1150, 'tax': 1050, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [178467]}, [178467, 608485]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| moderate losses between bounds | [455487, 827175] | [455487, 827175] | Passed |
| large claim limited | [5085219, 4610385] | [5085219, 4610385] | Passed |
| maximum binds | [14095709, 692363] | [14095709, 692363] | Passed |
| no losses minimum binds | [0, 164497] | [0, 391659] | Failed |
| subrogation recovery offsets | [227452, 581085] | [227452, 581085] | Passed |
| net recovery floors at zero | [0, 406002] | [0, 591265] | Failed |
| inverted bounds rejected | invalid bounds | invalid bounds | Passed |
| flat plan with equal bounds | [100000, 389535] | [100000, 929482] | Failed |
| near-minimum losses | [196003, 509523] | [196003, 509523] | Passed |
SHA-256 / 542c296335f8b3b2df9a7b353b2c6751346fa46720e6502d7a884fc99edf0fd5
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
sp=x['standard']
if x['max']<x['min']: return 'invalid bounds'
lim=max(0,sum(min(c,x['loss_limit']) for c in x['claims']))
basic=Fraction(sp*x['basic'],1000)
retro=(basic+Fraction(lim*x['lcf'],1000))*Fraction(x['tax'],1000)
lo=Fraction(sp*x['min'],1000); hi=Fraction(sp*x['max'],1000)
retro=max(lo,min(hi,retro)) if lim else retro
return [lim, math.floor(retro+Fraction(1,2))]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['moderate losses between bounds', {'standard': 1208187, 'basic': 250, 'lcf': 1100, 'tax': 1030, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [65251, 117766, 199866, 72604]}, [455487, 827175]], ['large claim limited', {'standard': 1536795, 'basic': 250, 'lcf': 1100, 'tax': 1050, 'min': 600, 'max': 3000, 'loss_limit': 5000000, 'claims': [7899385, 85219]}, [5085219, 4610385]], ['maximum binds', {'standard': 576969, 'basic': 250, 'lcf': 1100, 'tax': 1030, 'min': 500, 'max': 1200, 'loss_limit': 5000000, 'claims': [3887820, 3676391, 3519603, 3011895]}, [14095709, 692363]], ['no losses minimum binds', {'standard': 783317, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 500, 'max': 1400, 'loss_limit': 5000000, 'claims': []}, [0, 391659]], ['subrogation recovery offsets', {'standard': 1402360, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [299401, -71949]}, [227452, 581085]], ['net recovery floors at zero', {'standard': 1970882, 'basic': 200, 'lcf': 1150, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-13900]}, [0, 591265]], ['inverted bounds rejected', {'standard': 857821, 'basic': 200, 'lcf': 1150, 'tax': 1030, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 1032758, 'basic': 250, 'lcf': 1200, 'tax': 1030, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 929482]], ['near-minimum losses', {'standard': 1037917, 'basic': 250, 'lcf': 1200, 'tax': 1030, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [196003]}, [196003, 509523]]], [['moderate losses between bounds', {'standard': 559811, 'basic': 250, 'lcf': 1150, 'tax': 1030, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [168808, 170340, 188681, 153930]}, [681759, 951695]], ['large claim limited', {'standard': 1398667, 'basic': 200, 'lcf': 1150, 'tax': 1030, 'min': 500, 'max': 3000, 'loss_limit': 5000000, 'claims': [8563900, 72244]}, [5072244, 4196001]], ['maximum binds', {'standard': 1860838, 'basic': 250, 'lcf': 1100, 'tax': 1050, 'min': 600, 'max': 1200, 'loss_limit': 5000000, 'claims': [3974702, 2021857, 3323996, 2741110]}, [12061665, 2233006]], ['no losses minimum binds', {'standard': 1054836, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 500, 'max': 1400, 'loss_limit': 5000000, 'claims': []}, [0, 527418]], ['subrogation recovery offsets', {'standard': 572933, 'basic': 250, 'lcf': 1150, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [215865, -67794]}, [148071, 322920]], ['net recovery floors at zero', {'standard': 1415569, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-23951]}, [0, 424671]], ['inverted bounds rejected', {'standard': 1885857, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 1658903, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 1493013]], ['near-minimum losses', {'standard': 1831216, 'basic': 250, 'lcf': 1150, 'tax': 1030, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [255597]}, [255597, 824047]]], [['moderate losses between bounds', {'standard': 1953166, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [130486, 146045, 106267, 80838]}, [463636, 970005]], ['large claim limited', {'standard': 1375996, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 600, 'max': 3000, 'loss_limit': 5000000, 'claims': [8850428, 26063]}, [5026063, 4127988]], ['maximum binds', {'standard': 1822101, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 600, 'max': 1200, 'loss_limit': 5000000, 'claims': [3010425, 2467545, 2177771, 3447891]}, [11103632, 2186521]], ['no losses minimum binds', {'standard': 1516833, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 500, 'max': 1400, 'loss_limit': 5000000, 'claims': []}, [0, 758417]], ['subrogation recovery offsets', {'standard': 714829, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [292326, -101272]}, [191054, 370781]], ['net recovery floors at zero', {'standard': 1501098, 'basic': 200, 'lcf': 1100, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-22616]}, [0, 450329]], ['inverted bounds rejected', {'standard': 696781, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 802028, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 721825]], ['near-minimum losses', {'standard': 715359, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [161153]}, [161153, 346549]]], [['moderate losses between bounds', {'standard': 714988, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [147807, 50783, 101639, 147624]}, [447853, 714442]], ['large claim limited', {'standard': 1075364, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 600, 'max': 3000, 'loss_limit': 5000000, 'claims': [6621396, 51697]}, [5051697, 3226092]], ['maximum binds', {'standard': 636493, 'basic': 250, 'lcf': 1200, 'tax': 1050, 'min': 500, 'max': 1200, 'loss_limit': 5000000, 'claims': [3206066, 2811387, 2370852, 2596520]}, [10984825, 763792]], ['no losses minimum binds', {'standard': 1974481, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 500, 'max': 1600, 'loss_limit': 5000000, 'claims': []}, [0, 987241]], ['subrogation recovery offsets', {'standard': 1092045, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [210597, -95806]}, [114791, 366843]], ['net recovery floors at zero', {'standard': 1088467, 'basic': 250, 'lcf': 1200, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-13789]}, [0, 326540]], ['inverted bounds rejected', {'standard': 1508678, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 811592, 'basic': 250, 'lcf': 1200, 'tax': 1050, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 730433]], ['near-minimum losses', {'standard': 1513685, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [237641]}, [237641, 681158]]], [['moderate losses between bounds', {'standard': 1863348, 'basic': 250, 'lcf': 1200, 'tax': 1050, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [182396, 119506, 129126, 64521]}, [495549, 1113521]], ['large claim limited', {'standard': 1794820, 'basic': 200, 'lcf': 1100, 'tax': 1030, 'min': 500, 'max': 3000, 'loss_limit': 5000000, 'claims': [6997029, 30223]}, [5030223, 5384460]], ['maximum binds', {'standard': 1446879, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 500, 'max': 1200, 'loss_limit': 5000000, 'claims': [3226070, 2149089, 2381869, 2566788]}, [10323816, 1736255]], ['no losses minimum binds', {'standard': 1111989, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 500, 'max': 1400, 'loss_limit': 5000000, 'claims': []}, [0, 555995]], ['subrogation recovery offsets', {'standard': 930668, 'basic': 250, 'lcf': 1150, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [215001, -125166]}, [89835, 346057]], ['net recovery floors at zero', {'standard': 790663, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-24524]}, [0, 237199]], ['inverted bounds rejected', {'standard': 901935, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 802066, 'basic': 250, 'lcf': 1150, 'tax': 1050, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 721859]], ['near-minimum losses', {'standard': 1352189, 'basic': 250, 'lcf': 1150, 'tax': 1050, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [178467]}, [178467, 608485]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| moderate losses between bounds | [455487, 827175] | [455487, 827175] | Passed |
| large claim limited | [5085219, 4610385] | [5085219, 4610385] | Passed |
| maximum binds | [14095709, 692363] | [14095709, 692363] | Passed |
| no losses minimum binds | [0, 164497] | [0, 391659] | Failed |
| subrogation recovery offsets | [227452, 581085] | [227452, 581085] | Passed |
| net recovery floors at zero | [0, 406002] | [0, 591265] | Failed |
| inverted bounds rejected | invalid bounds | invalid bounds | Passed |
| flat plan with equal bounds | [100000, 929482] | [100000, 929482] | Passed |
| near-minimum losses | [196003, 509523] | [196003, 509523] | Passed |
SHA-256 / f9e4badc1c41ccb862684a4bad0318f72d01d295dd4ef669bf4b9d6c24446094
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
sp=x['standard']
if x['max']<x['min']: return 'invalid bounds'
lim=max(0,sum(min(c,x['loss_limit']) for c in x['claims']))
basic=Fraction(sp*x['basic'],1000)
retro=(basic+Fraction(lim*x['lcf'],1000))*Fraction(x['tax'],1000)
lo=Fraction(sp*x['min'],1000); hi=Fraction(sp*x['max'],1000)
retro=max(lo,min(hi,retro))
return [lim, math.floor(retro+Fraction(1,2))]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['moderate losses between bounds', {'standard': 1208187, 'basic': 250, 'lcf': 1100, 'tax': 1030, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [65251, 117766, 199866, 72604]}, [455487, 827175]], ['large claim limited', {'standard': 1536795, 'basic': 250, 'lcf': 1100, 'tax': 1050, 'min': 600, 'max': 3000, 'loss_limit': 5000000, 'claims': [7899385, 85219]}, [5085219, 4610385]], ['maximum binds', {'standard': 576969, 'basic': 250, 'lcf': 1100, 'tax': 1030, 'min': 500, 'max': 1200, 'loss_limit': 5000000, 'claims': [3887820, 3676391, 3519603, 3011895]}, [14095709, 692363]], ['no losses minimum binds', {'standard': 783317, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 500, 'max': 1400, 'loss_limit': 5000000, 'claims': []}, [0, 391659]], ['subrogation recovery offsets', {'standard': 1402360, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [299401, -71949]}, [227452, 581085]], ['net recovery floors at zero', {'standard': 1970882, 'basic': 200, 'lcf': 1150, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-13900]}, [0, 591265]], ['inverted bounds rejected', {'standard': 857821, 'basic': 200, 'lcf': 1150, 'tax': 1030, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 1032758, 'basic': 250, 'lcf': 1200, 'tax': 1030, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 929482]], ['near-minimum losses', {'standard': 1037917, 'basic': 250, 'lcf': 1200, 'tax': 1030, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [196003]}, [196003, 509523]]], [['moderate losses between bounds', {'standard': 559811, 'basic': 250, 'lcf': 1150, 'tax': 1030, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [168808, 170340, 188681, 153930]}, [681759, 951695]], ['large claim limited', {'standard': 1398667, 'basic': 200, 'lcf': 1150, 'tax': 1030, 'min': 500, 'max': 3000, 'loss_limit': 5000000, 'claims': [8563900, 72244]}, [5072244, 4196001]], ['maximum binds', {'standard': 1860838, 'basic': 250, 'lcf': 1100, 'tax': 1050, 'min': 600, 'max': 1200, 'loss_limit': 5000000, 'claims': [3974702, 2021857, 3323996, 2741110]}, [12061665, 2233006]], ['no losses minimum binds', {'standard': 1054836, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 500, 'max': 1400, 'loss_limit': 5000000, 'claims': []}, [0, 527418]], ['subrogation recovery offsets', {'standard': 572933, 'basic': 250, 'lcf': 1150, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [215865, -67794]}, [148071, 322920]], ['net recovery floors at zero', {'standard': 1415569, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-23951]}, [0, 424671]], ['inverted bounds rejected', {'standard': 1885857, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 1658903, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 1493013]], ['near-minimum losses', {'standard': 1831216, 'basic': 250, 'lcf': 1150, 'tax': 1030, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [255597]}, [255597, 824047]]], [['moderate losses between bounds', {'standard': 1953166, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [130486, 146045, 106267, 80838]}, [463636, 970005]], ['large claim limited', {'standard': 1375996, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 600, 'max': 3000, 'loss_limit': 5000000, 'claims': [8850428, 26063]}, [5026063, 4127988]], ['maximum binds', {'standard': 1822101, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 600, 'max': 1200, 'loss_limit': 5000000, 'claims': [3010425, 2467545, 2177771, 3447891]}, [11103632, 2186521]], ['no losses minimum binds', {'standard': 1516833, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 500, 'max': 1400, 'loss_limit': 5000000, 'claims': []}, [0, 758417]], ['subrogation recovery offsets', {'standard': 714829, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [292326, -101272]}, [191054, 370781]], ['net recovery floors at zero', {'standard': 1501098, 'basic': 200, 'lcf': 1100, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-22616]}, [0, 450329]], ['inverted bounds rejected', {'standard': 696781, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 802028, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 721825]], ['near-minimum losses', {'standard': 715359, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [161153]}, [161153, 346549]]], [['moderate losses between bounds', {'standard': 714988, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [147807, 50783, 101639, 147624]}, [447853, 714442]], ['large claim limited', {'standard': 1075364, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 600, 'max': 3000, 'loss_limit': 5000000, 'claims': [6621396, 51697]}, [5051697, 3226092]], ['maximum binds', {'standard': 636493, 'basic': 250, 'lcf': 1200, 'tax': 1050, 'min': 500, 'max': 1200, 'loss_limit': 5000000, 'claims': [3206066, 2811387, 2370852, 2596520]}, [10984825, 763792]], ['no losses minimum binds', {'standard': 1974481, 'basic': 200, 'lcf': 1200, 'tax': 1050, 'min': 500, 'max': 1600, 'loss_limit': 5000000, 'claims': []}, [0, 987241]], ['subrogation recovery offsets', {'standard': 1092045, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [210597, -95806]}, [114791, 366843]], ['net recovery floors at zero', {'standard': 1088467, 'basic': 250, 'lcf': 1200, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-13789]}, [0, 326540]], ['inverted bounds rejected', {'standard': 1508678, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 811592, 'basic': 250, 'lcf': 1200, 'tax': 1050, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 730433]], ['near-minimum losses', {'standard': 1513685, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [237641]}, [237641, 681158]]], [['moderate losses between bounds', {'standard': 1863348, 'basic': 250, 'lcf': 1200, 'tax': 1050, 'min': 400, 'max': 2000, 'loss_limit': 5000000, 'claims': [182396, 119506, 129126, 64521]}, [495549, 1113521]], ['large claim limited', {'standard': 1794820, 'basic': 200, 'lcf': 1100, 'tax': 1030, 'min': 500, 'max': 3000, 'loss_limit': 5000000, 'claims': [6997029, 30223]}, [5030223, 5384460]], ['maximum binds', {'standard': 1446879, 'basic': 200, 'lcf': 1200, 'tax': 1030, 'min': 500, 'max': 1200, 'loss_limit': 5000000, 'claims': [3226070, 2149089, 2381869, 2566788]}, [10323816, 1736255]], ['no losses minimum binds', {'standard': 1111989, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 500, 'max': 1400, 'loss_limit': 5000000, 'claims': []}, [0, 555995]], ['subrogation recovery offsets', {'standard': 930668, 'basic': 250, 'lcf': 1150, 'tax': 1030, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [215001, -125166]}, [89835, 346057]], ['net recovery floors at zero', {'standard': 790663, 'basic': 200, 'lcf': 1100, 'tax': 1050, 'min': 300, 'max': 2500, 'loss_limit': 5000000, 'claims': [-24524]}, [0, 237199]], ['inverted bounds rejected', {'standard': 901935, 'basic': 200, 'lcf': 1150, 'tax': 1050, 'min': 1300, 'max': 1200, 'loss_limit': 5000000, 'claims': [100000]}, 'invalid bounds'], ['flat plan with equal bounds', {'standard': 802066, 'basic': 250, 'lcf': 1150, 'tax': 1050, 'min': 900, 'max': 900, 'loss_limit': 5000000, 'claims': [100000]}, [100000, 721859]], ['near-minimum losses', {'standard': 1352189, 'basic': 250, 'lcf': 1150, 'tax': 1050, 'min': 450, 'max': 1800, 'loss_limit': 5000000, 'claims': [178467]}, [178467, 608485]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| moderate losses between bounds | [455487, 827175] | [455487, 827175] | Passed |
| large claim limited | [5085219, 4610385] | [5085219, 4610385] | Passed |
| maximum binds | [14095709, 692363] | [14095709, 692363] | Passed |
| no losses minimum binds | [0, 391659] | [0, 391659] | Passed |
| subrogation recovery offsets | [227452, 581085] | [227452, 581085] | Passed |
| net recovery floors at zero | [0, 591265] | [0, 591265] | Passed |
| inverted bounds rejected | invalid bounds | invalid bounds | Passed |
| flat plan with equal bounds | [100000, 929482] | [100000, 929482] | Passed |
| near-minimum losses | [196003, 509523] | [196003, 509523] | Passed |
SHA-256 / 50ab36a8a2313497decc30cf1f6ce97e562ded9227f7081a2c916606fe9b4e4e
Verification & scope
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.
Observations recorded using Python 3.12.14 at 2026-09-29T14:47:12.265224+00:00.
Case digest / a6e6323bb84657f389ca8130abd485f4594c5d458b8fb385180ae15272f81921