{"abstract":"Transactions on the day a tier takes effect earn at the old tier.","category":"Loyalty points ledgers","checks":7,"contract":"Input {tier_history:[[effective_day,tier]] (any order), txns:[[day,base]], mult:{tier:pct}}. Each transaction earns floor(base*pct/100) using the tier with the latest effective_day <= transaction day (\"member\" before any entry). Unknown tier names earn at 100%. Return {points, total}.","evaluation_group":"w2-loyalty-points-ledgers-tier-at-transaction","failed_approach":"Treating a tier as effective the day before over-applies it.","family":"w2-loyalty-points-ledgers-tier-at-transaction-effective-day-boundary","id":"FA-60746","implementations":{"attempt":{"sha256":"d3b391b2e6d09a3c992b507fe86e903cdc02b0d3629974ccc9ad9a4b3fabbabd","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    hist = sorted(x['tier_history'])\n    out = []\n    for day, base in x['txns']:\n        tier = 'member'\n        for eff, t in hist:\n            if eff <= day + 1:\n                tier = t\n            else:\n                break\n        pct = x['mult'].get(tier, 100)\n        out.append(base * pct // 100)\n    return {'points': out, 'total': sum(out)}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1001], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1251, 1500], 'total': 3751}], ['effective day', {'tier_history': [[100, 'silver'], [201, 'gold']], 'txns': [[100, 400], [201, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 101], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [151, 200], 'total': 351}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 334]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [334], 'total': 334}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 11]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 11], 'total': 88}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 201]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 251], 'total': 551}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 91]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [113], 'total': 113}]], [['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1002], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1252, 1500], 'total': 3752}], ['effective day', {'tier_history': [[100, 'silver'], [202, 'gold']], 'txns': [[100, 400], [202, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 102], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [153, 200], 'total': 353}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 335]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [335], 'total': 335}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 12]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 12], 'total': 89}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 202]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 252], 'total': 552}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 92]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [115], 'total': 115}]], [['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1003], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1253, 1500], 'total': 3753}], ['effective day', {'tier_history': [[100, 'silver'], [203, 'gold']], 'txns': [[100, 400], [203, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 103], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [154, 200], 'total': 354}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 336]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [336], 'total': 336}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 13]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 13], 'total': 90}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 203]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 253], 'total': 553}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 93]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [116], 'total': 116}]], [['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1004], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1255, 1500], 'total': 3755}], ['effective day', {'tier_history': [[100, 'silver'], [204, 'gold']], 'txns': [[100, 400], [204, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 104], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [156, 200], 'total': 356}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 337]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [337], 'total': 337}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 14]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 14], 'total': 91}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 204]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 255], 'total': 555}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 94]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [117], 'total': 117}]], [['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1005], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1256, 1500], 'total': 3756}], ['effective day', {'tier_history': [[100, 'silver'], [205, 'gold']], 'txns': [[100, 400], [205, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 105], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [157, 200], 'total': 357}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 338]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [338], 'total': 338}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 15]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 15], 'total': 92}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 205]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 256], 'total': 556}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 95]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [118], 'total': 118}]]]\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":"9d6c0acf5477791a7a173dfe41e16d2efa84d94812cd1e11cd68f73d95c31d46","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    hist = sorted(x['tier_history'])\n    out = []\n    for day, base in x['txns']:\n        tier = 'member'\n        for eff, t in hist:\n            if eff < day:\n                tier = t\n            else:\n                break\n        pct = x['mult'].get(tier, 100)\n        out.append(base * pct // 100)\n    return {'points': out, 'total': sum(out)}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1001], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1251, 1500], 'total': 3751}], ['effective day', {'tier_history': [[100, 'silver'], [201, 'gold']], 'txns': [[100, 400], [201, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 101], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [151, 200], 'total': 351}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 334]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [334], 'total': 334}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 11]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 11], 'total': 88}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 201]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 251], 'total': 551}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 91]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [113], 'total': 113}]], [['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1002], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1252, 1500], 'total': 3752}], ['effective day', {'tier_history': [[100, 'silver'], [202, 'gold']], 'txns': [[100, 400], [202, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 102], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [153, 200], 'total': 353}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 335]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [335], 'total': 335}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 12]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 12], 'total': 89}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 202]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 252], 'total': 552}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 92]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [115], 'total': 115}]], [['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1003], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1253, 1500], 'total': 3753}], ['effective day', {'tier_history': [[100, 'silver'], [203, 'gold']], 'txns': [[100, 400], [203, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 103], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [154, 200], 'total': 354}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 336]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [336], 'total': 336}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 13]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 13], 'total': 90}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 203]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 253], 'total': 553}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 93]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [116], 'total': 116}]], [['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1004], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1255, 1500], 'total': 3755}], ['effective day', {'tier_history': [[100, 'silver'], [204, 'gold']], 'txns': [[100, 400], [204, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 104], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [156, 200], 'total': 356}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 337]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [337], 'total': 337}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 14]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 14], 'total': 91}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 204]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 255], 'total': 555}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 94]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [117], 'total': 117}]], [['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1005], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1256, 1500], 'total': 3756}], ['effective day', {'tier_history': [[100, 'silver'], [205, 'gold']], 'txns': [[100, 400], [205, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 105], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [157, 200], 'total': 357}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 338]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [338], 'total': 338}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 15]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 15], 'total': 92}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 205]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 256], 'total': 556}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 95]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [118], 'total': 118}]]]\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":"a6aa004133bf274de7fb5e95d2650e5d09e58efe89ca92bbd37e211aad14dda3","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    hist = sorted(x['tier_history'])\n    out = []\n    for day, base in x['txns']:\n        tier = 'member'\n        for eff, t in hist:\n            if eff <= day:\n                tier = t\n            else:\n                break\n        pct = x['mult'].get(tier, 100)\n        out.append(base * pct // 100)\n    return {'points': out, 'total': sum(out)}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1001], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1251, 1500], 'total': 3751}], ['effective day', {'tier_history': [[100, 'silver'], [201, 'gold']], 'txns': [[100, 400], [201, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 101], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [151, 200], 'total': 351}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 334]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [334], 'total': 334}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 11]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 11], 'total': 88}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 201]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 251], 'total': 551}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 91]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [113], 'total': 113}]], [['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1002], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1252, 1500], 'total': 3752}], ['effective day', {'tier_history': [[100, 'silver'], [202, 'gold']], 'txns': [[100, 400], [202, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 102], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [153, 200], 'total': 353}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 335]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [335], 'total': 335}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 12]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 12], 'total': 89}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 202]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 252], 'total': 552}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 92]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [115], 'total': 115}]], [['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1003], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1253, 1500], 'total': 3753}], ['effective day', {'tier_history': [[100, 'silver'], [203, 'gold']], 'txns': [[100, 400], [203, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 103], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [154, 200], 'total': 354}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 336]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [336], 'total': 336}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 13]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 13], 'total': 90}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 203]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 253], 'total': 553}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 93]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [116], 'total': 116}]], [['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1004], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1255, 1500], 'total': 3755}], ['effective day', {'tier_history': [[100, 'silver'], [204, 'gold']], 'txns': [[100, 400], [204, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 104], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [156, 200], 'total': 356}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 337]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [337], 'total': 337}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 14]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 14], 'total': 91}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 204]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 255], 'total': 555}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 94]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [117], 'total': 117}]], [['tier changes midyear', {'tier_history': [[100, 'silver'], [200, 'gold']], 'txns': [[50, 1000], [150, 1005], [250, 1000]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [1000, 1256, 1500], 'total': 3756}], ['effective day', {'tier_history': [[100, 'silver'], [205, 'gold']], 'txns': [[100, 400], [205, 400]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [500, 600], 'total': 1100}], ['unsorted history', {'tier_history': [[300, 'platinum'], [100, 'gold']], 'txns': [[150, 105], [350, 100]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [157, 200], 'total': 357}], ['legacy tier', {'tier_history': [[10, 'diamond']], 'txns': [[20, 338]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [338], 'total': 338}], ['before any tier', {'tier_history': [[500, 'gold']], 'txns': [[1, 77], [499, 15]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [77, 15], 'total': 92}], ['downgrade', {'tier_history': [[10, 'gold'], [60, 'silver']], 'txns': [[59, 200], [61, 205]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [300, 256], 'total': 556}], ['late earns', {'tier_history': [[0, 'silver'], [30, 'platinum']], 'txns': [[15, 95]], 'mult': {'member': 100, 'silver': 125, 'gold': 150, 'platinum': 200}}, {'points': [118], 'total': 118}]]]\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-tier-at-transaction-effective-day-boundary","generated_at":"2026-09-29T14:46:48.550351+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":"A tier applies from its effective day inclusive.","root_cause":"The effective test uses < instead of <=.","sha256":"8309d653aa7f86d415c28e595fc7037a4856a9701ed84f6a6826425013949a26","title":"Tier multiplier in force at transaction time: effective day boundary · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":40.497,"exit_code":1,"observations":[{"actual":{"points":[1000,1251,1500],"total":3751},"check":"tier changes midyear","expected":{"points":[1000,1251,1500],"total":3751},"passed":true},{"actual":{"points":[500,600],"total":1100},"check":"effective day","expected":{"points":[500,600],"total":1100},"passed":true},{"actual":{"points":[151,200],"total":351},"check":"unsorted history","expected":{"points":[151,200],"total":351},"passed":true},{"actual":{"points":[334],"total":334},"check":"legacy tier","expected":{"points":[334],"total":334},"passed":true},{"actual":{"points":[77,16],"total":93},"check":"before any tier","expected":{"points":[77,11],"total":88},"passed":false},{"actual":{"points":[250,251],"total":501},"check":"downgrade","expected":{"points":[300,251],"total":551},"passed":false},{"actual":{"points":[113],"total":113},"check":"late earns","expected":{"points":[113],"total":113},"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"tier changes midyear\", \"actual\": {\"points\": [1000, 1251, 1500], \"total\": 3751}, \"expected\": {\"points\": [1000, 1251, 1500], \"total\": 3751}, \"passed\": true}, {\"check\": \"effective day\", \"actual\": {\"points\": [500, 600], \"total\": 1100}, \"expected\": {\"points\": [500, 600], \"total\": 1100}, \"passed\": true}, {\"check\": \"unsorted history\", \"actual\": {\"points\": [151, 200], \"total\": 351}, \"expected\": {\"points\": [151, 200], \"total\": 351}, \"passed\": true}, {\"check\": \"legacy tier\", \"actual\": {\"points\": [334], \"total\": 334}, \"expected\": {\"points\": [334], \"total\": 334}, \"passed\": true}, {\"check\": \"before any tier\", \"actual\": {\"points\": [77, 16], \"total\": 93}, \"expected\": {\"points\": [77, 11], \"total\": 88}, \"passed\": false}, {\"check\": \"downgrade\", \"actual\": {\"points\": [250, 251], \"total\": 501}, \"expected\": {\"points\": [300, 251], \"total\": 551}, \"passed\": false}, {\"check\": \"late earns\", \"actual\": {\"points\": [113], \"total\": 113}, \"expected\": {\"points\": [113], \"total\": 113}, \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.595,"exit_code":1,"observations":[{"actual":{"points":[1000,1251,1500],"total":3751},"check":"tier changes midyear","expected":{"points":[1000,1251,1500],"total":3751},"passed":true},{"actual":{"points":[400,500],"total":900},"check":"effective day","expected":{"points":[500,600],"total":1100},"passed":false},{"actual":{"points":[151,200],"total":351},"check":"unsorted history","expected":{"points":[151,200],"total":351},"passed":true},{"actual":{"points":[334],"total":334},"check":"legacy tier","expected":{"points":[334],"total":334},"passed":true},{"actual":{"points":[77,11],"total":88},"check":"before any tier","expected":{"points":[77,11],"total":88},"passed":true},{"actual":{"points":[300,251],"total":551},"check":"downgrade","expected":{"points":[300,251],"total":551},"passed":true},{"actual":{"points":[113],"total":113},"check":"late earns","expected":{"points":[113],"total":113},"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"tier changes midyear\", \"actual\": {\"points\": [1000, 1251, 1500], \"total\": 3751}, \"expected\": {\"points\": [1000, 1251, 1500], \"total\": 3751}, \"passed\": true}, {\"check\": \"effective day\", \"actual\": {\"points\": [400, 500], \"total\": 900}, \"expected\": {\"points\": [500, 600], \"total\": 1100}, \"passed\": false}, {\"check\": \"unsorted history\", \"actual\": {\"points\": [151, 200], \"total\": 351}, \"expected\": {\"points\": [151, 200], \"total\": 351}, \"passed\": true}, {\"check\": \"legacy tier\", \"actual\": {\"points\": [334], \"total\": 334}, \"expected\": {\"points\": [334], \"total\": 334}, \"passed\": true}, {\"check\": \"before any tier\", \"actual\": {\"points\": [77, 11], \"total\": 88}, \"expected\": {\"points\": [77, 11], \"total\": 88}, \"passed\": true}, {\"check\": \"downgrade\", \"actual\": {\"points\": [300, 251], \"total\": 551}, \"expected\": {\"points\": [300, 251], \"total\": 551}, \"passed\": true}, {\"check\": \"late earns\", \"actual\": {\"points\": [113], \"total\": 113}, \"expected\": {\"points\": [113], \"total\": 113}, \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":41.45,"exit_code":0,"observations":[{"actual":{"points":[1000,1251,1500],"total":3751},"check":"tier changes midyear","expected":{"points":[1000,1251,1500],"total":3751},"passed":true},{"actual":{"points":[500,600],"total":1100},"check":"effective day","expected":{"points":[500,600],"total":1100},"passed":true},{"actual":{"points":[151,200],"total":351},"check":"unsorted history","expected":{"points":[151,200],"total":351},"passed":true},{"actual":{"points":[334],"total":334},"check":"legacy tier","expected":{"points":[334],"total":334},"passed":true},{"actual":{"points":[77,11],"total":88},"check":"before any tier","expected":{"points":[77,11],"total":88},"passed":true},{"actual":{"points":[300,251],"total":551},"check":"downgrade","expected":{"points":[300,251],"total":551},"passed":true},{"actual":{"points":[113],"total":113},"check":"late earns","expected":{"points":[113],"total":113},"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"tier changes midyear\", \"actual\": {\"points\": [1000, 1251, 1500], \"total\": 3751}, \"expected\": {\"points\": [1000, 1251, 1500], \"total\": 3751}, \"passed\": true}, {\"check\": \"effective day\", \"actual\": {\"points\": [500, 600], \"total\": 1100}, \"expected\": {\"points\": [500, 600], \"total\": 1100}, \"passed\": true}, {\"check\": \"unsorted history\", \"actual\": {\"points\": [151, 200], \"total\": 351}, \"expected\": {\"points\": [151, 200], \"total\": 351}, \"passed\": true}, {\"check\": \"legacy tier\", \"actual\": {\"points\": [334], \"total\": 334}, \"expected\": {\"points\": [334], \"total\": 334}, \"passed\": true}, {\"check\": \"before any tier\", \"actual\": {\"points\": [77, 11], \"total\": 88}, \"expected\": {\"points\": [77, 11], \"total\": 88}, \"passed\": true}, {\"check\": \"downgrade\", \"actual\": {\"points\": [300, 251], \"total\": 551}, \"expected\": {\"points\": [300, 251], \"total\": 551}, \"passed\": true}, {\"check\": \"late earns\", \"actual\": {\"points\": [113], \"total\": 113}, \"expected\": {\"points\": [113], \"total\": 113}, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}