{"abstract":"Revenue is recognized only at face value per redeemed point, ignoring expected breakage.","category":"Loyalty points ledgers","checks":7,"contract":"Input {issued, redeemed, value_mc (millicents per point), breakage_bp}. Deferred revenue = floor(issued*value_mc/1000) cents. Expected redemptions = floor(issued*(10000-breakage_bp)/10000); if zero return {\"error\"}. Recognized = floor(deferred*min(redeemed, expected)/expected); liability = deferred - recognized. Return {deferred, expected, recognized, liability}.","evaluation_group":"w2-loyalty-points-ledgers-breakage-recognition","failed_approach":"Grossing face value up by the breakage rate approximates but does not equal the proportional method.","family":"w2-loyalty-points-ledgers-breakage-recognition-breakage-acceleration","id":"FA-60601","implementations":{"attempt":{"sha256":"af814f655b85318d2282a98d798bac62b97902a7e2afb5b678d830f786f460c0","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    deferred = x['issued'] * x['value_mc'] // 1000\n    expected = x['issued'] * (10000 - x['breakage_bp']) // 10000\n    if expected <= 0:\n        return {'error': 'no expected redemptions'}\n    used = min(x['redeemed'], expected)\n    recognized = used * x['value_mc'] * (10000 + x['breakage_bp']) // 10000000\n    return {'deferred': deferred, 'expected': expected, 'recognized': recognized, 'liability': deferred - recognized}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['mid program', {'issued': 100000, 'redeemed': 30001, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37501, 'liability': 62499}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1001}, {'deferred': 40000, 'expected': 44995, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1112, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1112, 'liability': 1387}], ['no breakage', {'issued': 700, 'redeemed': 351, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 351, 'liability': 349}], ['all breakage', {'issued': 700, 'redeemed': 1, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 4, 'breakage_bp': 3000}, {'deferred': 399, 'expected': 69999, 'recognized': 70, 'liability': 329}]], [['mid program', {'issued': 100000, 'redeemed': 30002, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37502, 'liability': 62498}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1002}, {'deferred': 40000, 'expected': 44990, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1113, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1113, 'liability': 1386}], ['no breakage', {'issued': 700, 'redeemed': 352, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 352, 'liability': 348}], ['all breakage', {'issued': 700, 'redeemed': 2, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 5, 'breakage_bp': 3000}, {'deferred': 499, 'expected': 69999, 'recognized': 88, 'liability': 411}]], [['mid program', {'issued': 100000, 'redeemed': 30003, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37503, 'liability': 62497}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1003}, {'deferred': 40000, 'expected': 44985, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1114, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1114, 'liability': 1385}], ['no breakage', {'issued': 700, 'redeemed': 353, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 353, 'liability': 347}], ['all breakage', {'issued': 700, 'redeemed': 3, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 6, 'breakage_bp': 3000}, {'deferred': 599, 'expected': 69999, 'recognized': 105, 'liability': 494}]], [['mid program', {'issued': 100000, 'redeemed': 30004, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37505, 'liability': 62495}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1004}, {'deferred': 40000, 'expected': 44980, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1115, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1115, 'liability': 1384}], ['no breakage', {'issued': 700, 'redeemed': 354, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 354, 'liability': 346}], ['all breakage', {'issued': 700, 'redeemed': 4, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 7, 'breakage_bp': 3000}, {'deferred': 699, 'expected': 69999, 'recognized': 123, 'liability': 576}]], [['mid program', {'issued': 100000, 'redeemed': 30005, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37506, 'liability': 62494}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1005}, {'deferred': 40000, 'expected': 44975, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1116, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1116, 'liability': 1383}], ['no breakage', {'issued': 700, 'redeemed': 355, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 355, 'liability': 345}], ['all breakage', {'issued': 700, 'redeemed': 5, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 8, 'breakage_bp': 3000}, {'deferred': 799, 'expected': 69999, 'recognized': 140, 'liability': 659}]]]\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":"28f1113edcfda0ab211d5da925316d2a35b73036d0e133af392639eb03c3df72","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    deferred = x['issued'] * x['value_mc'] // 1000\n    expected = x['issued'] * (10000 - x['breakage_bp']) // 10000\n    if expected <= 0:\n        return {'error': 'no expected redemptions'}\n    used = min(x['redeemed'], expected)\n    recognized = used * x['value_mc'] // 1000\n    return {'deferred': deferred, 'expected': expected, 'recognized': recognized, 'liability': deferred - recognized}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['mid program', {'issued': 100000, 'redeemed': 30001, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37501, 'liability': 62499}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1001}, {'deferred': 40000, 'expected': 44995, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1112, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1112, 'liability': 1387}], ['no breakage', {'issued': 700, 'redeemed': 351, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 351, 'liability': 349}], ['all breakage', {'issued': 700, 'redeemed': 1, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 4, 'breakage_bp': 3000}, {'deferred': 399, 'expected': 69999, 'recognized': 70, 'liability': 329}]], [['mid program', {'issued': 100000, 'redeemed': 30002, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37502, 'liability': 62498}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1002}, {'deferred': 40000, 'expected': 44990, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1113, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1113, 'liability': 1386}], ['no breakage', {'issued': 700, 'redeemed': 352, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 352, 'liability': 348}], ['all breakage', {'issued': 700, 'redeemed': 2, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 5, 'breakage_bp': 3000}, {'deferred': 499, 'expected': 69999, 'recognized': 88, 'liability': 411}]], [['mid program', {'issued': 100000, 'redeemed': 30003, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37503, 'liability': 62497}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1003}, {'deferred': 40000, 'expected': 44985, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1114, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1114, 'liability': 1385}], ['no breakage', {'issued': 700, 'redeemed': 353, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 353, 'liability': 347}], ['all breakage', {'issued': 700, 'redeemed': 3, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 6, 'breakage_bp': 3000}, {'deferred': 599, 'expected': 69999, 'recognized': 105, 'liability': 494}]], [['mid program', {'issued': 100000, 'redeemed': 30004, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37505, 'liability': 62495}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1004}, {'deferred': 40000, 'expected': 44980, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1115, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1115, 'liability': 1384}], ['no breakage', {'issued': 700, 'redeemed': 354, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 354, 'liability': 346}], ['all breakage', {'issued': 700, 'redeemed': 4, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 7, 'breakage_bp': 3000}, {'deferred': 699, 'expected': 69999, 'recognized': 123, 'liability': 576}]], [['mid program', {'issued': 100000, 'redeemed': 30005, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37506, 'liability': 62494}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1005}, {'deferred': 40000, 'expected': 44975, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1116, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1116, 'liability': 1383}], ['no breakage', {'issued': 700, 'redeemed': 355, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 355, 'liability': 345}], ['all breakage', {'issued': 700, 'redeemed': 5, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 8, 'breakage_bp': 3000}, {'deferred': 799, 'expected': 69999, 'recognized': 140, 'liability': 659}]]]\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":"706960ac1820d2a9bad824de1f32ae415e5461d59821348a885a754271cc68cb","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    deferred = x['issued'] * x['value_mc'] // 1000\n    expected = x['issued'] * (10000 - x['breakage_bp']) // 10000\n    if expected <= 0:\n        return {'error': 'no expected redemptions'}\n    used = min(x['redeemed'], expected)\n    recognized = deferred * used // expected\n    return {'deferred': deferred, 'expected': expected, 'recognized': recognized, 'liability': deferred - recognized}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['mid program', {'issued': 100000, 'redeemed': 30001, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37501, 'liability': 62499}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1001}, {'deferred': 40000, 'expected': 44995, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1112, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1112, 'liability': 1387}], ['no breakage', {'issued': 700, 'redeemed': 351, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 351, 'liability': 349}], ['all breakage', {'issued': 700, 'redeemed': 1, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 4, 'breakage_bp': 3000}, {'deferred': 399, 'expected': 69999, 'recognized': 70, 'liability': 329}]], [['mid program', {'issued': 100000, 'redeemed': 30002, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37502, 'liability': 62498}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1002}, {'deferred': 40000, 'expected': 44990, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1113, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1113, 'liability': 1386}], ['no breakage', {'issued': 700, 'redeemed': 352, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 352, 'liability': 348}], ['all breakage', {'issued': 700, 'redeemed': 2, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 5, 'breakage_bp': 3000}, {'deferred': 499, 'expected': 69999, 'recognized': 88, 'liability': 411}]], [['mid program', {'issued': 100000, 'redeemed': 30003, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37503, 'liability': 62497}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1003}, {'deferred': 40000, 'expected': 44985, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1114, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1114, 'liability': 1385}], ['no breakage', {'issued': 700, 'redeemed': 353, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 353, 'liability': 347}], ['all breakage', {'issued': 700, 'redeemed': 3, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 6, 'breakage_bp': 3000}, {'deferred': 599, 'expected': 69999, 'recognized': 105, 'liability': 494}]], [['mid program', {'issued': 100000, 'redeemed': 30004, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37505, 'liability': 62495}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1004}, {'deferred': 40000, 'expected': 44980, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1115, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1115, 'liability': 1384}], ['no breakage', {'issued': 700, 'redeemed': 354, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 354, 'liability': 346}], ['all breakage', {'issued': 700, 'redeemed': 4, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 7, 'breakage_bp': 3000}, {'deferred': 699, 'expected': 69999, 'recognized': 123, 'liability': 576}]], [['mid program', {'issued': 100000, 'redeemed': 30005, 'value_mc': 1000, 'breakage_bp': 2000}, {'deferred': 100000, 'expected': 80000, 'recognized': 37506, 'liability': 62494}], ['fully redeemed', {'issued': 50000, 'redeemed': 45000, 'value_mc': 800, 'breakage_bp': 1005}, {'deferred': 40000, 'expected': 44975, 'recognized': 40000, 'liability': 0}], ['over redeemed', {'issued': 1000, 'redeemed': 950, 'value_mc': 1200, 'breakage_bp': 1500}, {'deferred': 1200, 'expected': 850, 'recognized': 1200, 'liability': 0}], ['fractional value', {'issued': 3333, 'redeemed': 1116, 'value_mc': 750, 'breakage_bp': 2500}, {'deferred': 2499, 'expected': 2499, 'recognized': 1116, 'liability': 1383}], ['no breakage', {'issued': 700, 'redeemed': 355, 'value_mc': 1000, 'breakage_bp': 0}, {'deferred': 700, 'expected': 700, 'recognized': 355, 'liability': 345}], ['all breakage', {'issued': 700, 'redeemed': 5, 'value_mc': 1000, 'breakage_bp': 10000}, {'error': 'no expected redemptions'}], ['tiny value', {'issued': 99999, 'redeemed': 12345, 'value_mc': 8, 'breakage_bp': 3000}, {'deferred': 799, 'expected': 69999, 'recognized': 140, 'liability': 659}]]]\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 loyalty-program model with explicit toy rules; not any real program terms. 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-loyalty-points-ledgers-breakage-recognition-breakage-acceleration","generated_at":"2026-09-29T14:46:47.217596+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Member point balances, statements and the program liability depend on this ledger rule.","repair":"Recognize deferred revenue in proportion to redemptions over expected redemptions.","root_cause":"Recognition uses redeemed points times value instead of the proportional method.","sha256":"a33a1c6e5724b6697af225dcccb4467ffba38f9da7c19c904d483de607b11efa","title":"Breakage-based revenue recognition: breakage acceleration · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":48.401,"exit_code":1,"observations":[{"actual":{"deferred":100000,"expected":80000,"liability":63999,"recognized":36001},"check":"mid program","expected":{"deferred":100000,"expected":80000,"liability":62499,"recognized":37501},"passed":false},{"actual":{"deferred":40000,"expected":44995,"liability":401,"recognized":39599},"check":"fully redeemed","expected":{"deferred":40000,"expected":44995,"liability":0,"recognized":40000},"passed":false},{"actual":{"deferred":1200,"expected":850,"liability":27,"recognized":1173},"check":"over redeemed","expected":{"deferred":1200,"expected":850,"liability":0,"recognized":1200},"passed":false},{"actual":{"deferred":2499,"expected":2499,"liability":1457,"recognized":1042},"check":"fractional value","expected":{"deferred":2499,"expected":2499,"liability":1387,"recognized":1112},"passed":false},{"actual":{"deferred":700,"expected":700,"liability":349,"recognized":351},"check":"no breakage","expected":{"deferred":700,"expected":700,"liability":349,"recognized":351},"passed":true},{"actual":{"error":"no expected redemptions"},"check":"all breakage","expected":{"error":"no expected redemptions"},"passed":true},{"actual":{"deferred":399,"expected":69999,"liability":335,"recognized":64},"check":"tiny value","expected":{"deferred":399,"expected":69999,"liability":329,"recognized":70},"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"mid program\", \"actual\": {\"deferred\": 100000, \"expected\": 80000, \"recognized\": 36001, \"liability\": 63999}, \"expected\": {\"deferred\": 100000, \"expected\": 80000, \"recognized\": 37501, \"liability\": 62499}, \"passed\": false}, {\"check\": \"fully redeemed\", \"actual\": {\"deferred\": 40000, \"expected\": 44995, \"recognized\": 39599, \"liability\": 401}, \"expected\": {\"deferred\": 40000, \"expected\": 44995, \"recognized\": 40000, \"liability\": 0}, \"passed\": false}, {\"check\": \"over redeemed\", \"actual\": {\"deferred\": 1200, \"expected\": 850, \"recognized\": 1173, \"liability\": 27}, \"expected\": {\"deferred\": 1200, \"expected\": 850, \"recognized\": 1200, \"liability\": 0}, \"passed\": false}, {\"check\": \"fractional value\", \"actual\": {\"deferred\": 2499, \"expected\": 2499, \"recognized\": 1042, \"liability\": 1457}, \"expected\": {\"deferred\": 2499, \"expected\": 2499, \"recognized\": 1112, \"liability\": 1387}, \"passed\": false}, {\"check\": \"no breakage\", \"actual\": {\"deferred\": 700, \"expected\": 700, \"recognized\": 351, \"liability\": 349}, \"expected\": {\"deferred\": 700, \"expected\": 700, \"recognized\": 351, \"liability\": 349}, \"passed\": true}, {\"check\": \"all breakage\", \"actual\": {\"error\": \"no expected redemptions\"}, \"expected\": {\"error\": \"no expected redemptions\"}, \"passed\": true}, {\"check\": \"tiny value\", \"actual\": {\"deferred\": 399, \"expected\": 69999, \"recognized\": 64, \"liability\": 335}, \"expected\": {\"deferred\": 399, \"expected\": 69999, \"recognized\": 70, \"liability\": 329}, \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":46.406,"exit_code":1,"observations":[{"actual":{"deferred":100000,"expected":80000,"liability":69999,"recognized":30001},"check":"mid program","expected":{"deferred":100000,"expected":80000,"liability":62499,"recognized":37501},"passed":false},{"actual":{"deferred":40000,"expected":44995,"liability":4004,"recognized":35996},"check":"fully redeemed","expected":{"deferred":40000,"expected":44995,"liability":0,"recognized":40000},"passed":false},{"actual":{"deferred":1200,"expected":850,"liability":180,"recognized":1020},"check":"over redeemed","expected":{"deferred":1200,"expected":850,"liability":0,"recognized":1200},"passed":false},{"actual":{"deferred":2499,"expected":2499,"liability":1665,"recognized":834},"check":"fractional value","expected":{"deferred":2499,"expected":2499,"liability":1387,"recognized":1112},"passed":false},{"actual":{"deferred":700,"expected":700,"liability":349,"recognized":351},"check":"no breakage","expected":{"deferred":700,"expected":700,"liability":349,"recognized":351},"passed":true},{"actual":{"error":"no expected redemptions"},"check":"all breakage","expected":{"error":"no expected redemptions"},"passed":true},{"actual":{"deferred":399,"expected":69999,"liability":350,"recognized":49},"check":"tiny value","expected":{"deferred":399,"expected":69999,"liability":329,"recognized":70},"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"mid program\", \"actual\": {\"deferred\": 100000, \"expected\": 80000, \"recognized\": 30001, \"liability\": 69999}, \"expected\": {\"deferred\": 100000, \"expected\": 80000, \"recognized\": 37501, \"liability\": 62499}, \"passed\": false}, {\"check\": \"fully redeemed\", \"actual\": {\"deferred\": 40000, \"expected\": 44995, \"recognized\": 35996, \"liability\": 4004}, \"expected\": {\"deferred\": 40000, \"expected\": 44995, \"recognized\": 40000, \"liability\": 0}, \"passed\": false}, {\"check\": \"over redeemed\", \"actual\": {\"deferred\": 1200, \"expected\": 850, \"recognized\": 1020, \"liability\": 180}, \"expected\": {\"deferred\": 1200, \"expected\": 850, \"recognized\": 1200, \"liability\": 0}, \"passed\": false}, {\"check\": \"fractional value\", \"actual\": {\"deferred\": 2499, \"expected\": 2499, \"recognized\": 834, \"liability\": 1665}, \"expected\": {\"deferred\": 2499, \"expected\": 2499, \"recognized\": 1112, \"liability\": 1387}, \"passed\": false}, {\"check\": \"no breakage\", \"actual\": {\"deferred\": 700, \"expected\": 700, \"recognized\": 351, \"liability\": 349}, \"expected\": {\"deferred\": 700, \"expected\": 700, \"recognized\": 351, \"liability\": 349}, \"passed\": true}, {\"check\": \"all breakage\", \"actual\": {\"error\": \"no expected redemptions\"}, \"expected\": {\"error\": \"no expected redemptions\"}, \"passed\": true}, {\"check\": \"tiny value\", \"actual\": {\"deferred\": 399, \"expected\": 69999, \"recognized\": 49, \"liability\": 350}, \"expected\": {\"deferred\": 399, \"expected\": 69999, \"recognized\": 70, \"liability\": 329}, \"passed\": false}], \"passed\": false}\n"},"fixed":{"elapsed_ms":44.359,"exit_code":0,"observations":[{"actual":{"deferred":100000,"expected":80000,"liability":62499,"recognized":37501},"check":"mid program","expected":{"deferred":100000,"expected":80000,"liability":62499,"recognized":37501},"passed":true},{"actual":{"deferred":40000,"expected":44995,"liability":0,"recognized":40000},"check":"fully redeemed","expected":{"deferred":40000,"expected":44995,"liability":0,"recognized":40000},"passed":true},{"actual":{"deferred":1200,"expected":850,"liability":0,"recognized":1200},"check":"over redeemed","expected":{"deferred":1200,"expected":850,"liability":0,"recognized":1200},"passed":true},{"actual":{"deferred":2499,"expected":2499,"liability":1387,"recognized":1112},"check":"fractional value","expected":{"deferred":2499,"expected":2499,"liability":1387,"recognized":1112},"passed":true},{"actual":{"deferred":700,"expected":700,"liability":349,"recognized":351},"check":"no breakage","expected":{"deferred":700,"expected":700,"liability":349,"recognized":351},"passed":true},{"actual":{"error":"no expected redemptions"},"check":"all breakage","expected":{"error":"no expected redemptions"},"passed":true},{"actual":{"deferred":399,"expected":69999,"liability":329,"recognized":70},"check":"tiny value","expected":{"deferred":399,"expected":69999,"liability":329,"recognized":70},"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"mid program\", \"actual\": {\"deferred\": 100000, \"expected\": 80000, \"recognized\": 37501, \"liability\": 62499}, \"expected\": {\"deferred\": 100000, \"expected\": 80000, \"recognized\": 37501, \"liability\": 62499}, \"passed\": true}, {\"check\": \"fully redeemed\", \"actual\": {\"deferred\": 40000, \"expected\": 44995, \"recognized\": 40000, \"liability\": 0}, \"expected\": {\"deferred\": 40000, \"expected\": 44995, \"recognized\": 40000, \"liability\": 0}, \"passed\": true}, {\"check\": \"over redeemed\", \"actual\": {\"deferred\": 1200, \"expected\": 850, \"recognized\": 1200, \"liability\": 0}, \"expected\": {\"deferred\": 1200, \"expected\": 850, \"recognized\": 1200, \"liability\": 0}, \"passed\": true}, {\"check\": \"fractional value\", \"actual\": {\"deferred\": 2499, \"expected\": 2499, \"recognized\": 1112, \"liability\": 1387}, \"expected\": {\"deferred\": 2499, \"expected\": 2499, \"recognized\": 1112, \"liability\": 1387}, \"passed\": true}, {\"check\": \"no breakage\", \"actual\": {\"deferred\": 700, \"expected\": 700, \"recognized\": 351, \"liability\": 349}, \"expected\": {\"deferred\": 700, \"expected\": 700, \"recognized\": 351, \"liability\": 349}, \"passed\": true}, {\"check\": \"all breakage\", \"actual\": {\"error\": \"no expected redemptions\"}, \"expected\": {\"error\": \"no expected redemptions\"}, \"passed\": true}, {\"check\": \"tiny value\", \"actual\": {\"deferred\": 399, \"expected\": 69999, \"recognized\": 70, \"liability\": 329}, \"expected\": {\"deferred\": 399, \"expected\": 69999, \"recognized\": 70, \"liability\": 329}, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}