{"abstract":"Rested pool goes negative after a large gain.","category":"Game economy crafting balance","checks":8,"contract":"Level L needs 80 + 20*L xp to reach L+1; max level 50. Gains are ignored once level 50 is reached (rested untouched). For each gain g: bonus = min(g, rested) is added on top of g and removed from the rested pool; then as many levels as possible are taken, carrying remaining xp; on reaching level 50 the xp bar is set to 0. Returns [level, xp, rested].","evaluation_group":"w2-game-economy-crafting-balance-rested-xp","failed_approach":"Charging twice the bonus drains the pool at double rate.","family":"w2-game-economy-crafting-balance-rested-xp-rested-drain","id":"FA-86316","implementations":{"attempt":{"sha256":"097b6ca305c8b1c3dee41dca47d8d644d123b509320e466b3fc0f5015e9cba47","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(level, xp, gains, rested):\n    for g in gains:\n        if level >= 50:\n            break\n        bonus = min(g, rested)\n        rested -= bonus * 2\n        xp += g + bonus\n        while level < 50 and xp >= 80 + 20 * level:\n            xp -= 80 + 20 * level\n            level += 1\n        if level >= 50:\n            xp = 0\n    return [level, xp, rested]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),\n  ('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),\n  ('regression rested drain #1', [48, 123, [50, 10, 420], 100], [48, 703, 0]),\n  ('regression rested drain #2', [48, 108, [300, 300, 99, 86, 300], 30], [49, 183, 0]),\n  ('partial repair boundary #1', [30, 20, [50, 100, 10, 10], 1000], [30, 360, 830]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 56, [99], 100], [50, 56, 100]),\n  ('control #2', [50, 12, [2000, 50, 300, 50], 30], [50, 12, 30])],\n [('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),\n  ('regression rested drain #1', [48, 123, [50, 10, 420], 100], [48, 703, 0]),\n  ('fault site rested drain #1', [5, 79, [300], 0], [6, 199, 0]),\n  ('partial repair boundary #1', [30, 20, [50, 100, 10, 10], 1000], [30, 360, 830]),\n  ('regression rested drain #2', [1, 37, [100, 100, 2000], 1000], [15, 17, 0]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 12, [2000, 50, 300, 50], 30], [50, 12, 30]),\n  ('control #2', [50, 44, [10], 100], [50, 44, 100])],\n [('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),\n  ('fault site rested drain #1', [10, 7, [300, 50, 99, 100], 0], [11, 276, 0]),\n  ('regression rested drain #1', [48, 108, [300, 300, 99, 86, 300], 30], [49, 183, 0]),\n  ('partial repair boundary #1', [1, 15, [100], 100], [2, 115, 0]),\n  ('partial repair boundary #2', [48, 26, [100, 99], 1000], [48, 424, 801]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 110, [50, 10], 0], [50, 110, 0]),\n  ('control #2', [50, 62, [300, 2000, 300], 100], [50, 62, 100])],\n [('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),\n  ('fault site rested drain #1', [5, 79, [100, 10, 2000], 0], [13, 189, 0]),\n  ('fault site rested drain #2', [29, 125, [2000], 0], [32, 85, 0]),\n  ('regression rested drain #1', [5, 102, [50, 100], 30], [6, 102, 0]),\n  ('regression rested drain #2', [5, 92, [179, 50, 437, 100], 155], [9, 173, 0]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 124, [100, 300, 2000, 415], 1000], [50, 124, 1000]),\n  ('control #2', [50, 85, [10, 207, 99], 0], [50, 85, 0])],\n [('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),\n  ('fault site rested drain #1', [30, 122, [50, 10, 300, 50, 100], 0], [30, 632, 0]),\n  ('regression rested drain #1', [1, 37, [100, 100, 2000], 1000], [15, 17, 0]),\n  ('regression rested drain #2', [1, 19, [50, 2000, 50], 1000], [14, 259, 0]),\n  ('regression rested drain #3', [30, 136, [2000, 100], 1000], [34, 396, 0]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 29, [10, 249, 50, 100], 0], [50, 29, 0]),\n  ('control #2', [50, 145, [10], 80], [50, 145, 80])]]\nfor label, args, expected in cases[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":"779cf606b8d3afce3c6eb49428c4483009f06f0a3bb56978ced6879f478af0d6","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(level, xp, gains, rested):\n    for g in gains:\n        if level >= 50:\n            break\n        bonus = min(g, rested)\n        rested -= g\n        xp += g + bonus\n        while level < 50 and xp >= 80 + 20 * level:\n            xp -= 80 + 20 * level\n            level += 1\n        if level >= 50:\n            xp = 0\n    return [level, xp, rested]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),\n  ('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),\n  ('regression rested drain #1', [48, 123, [50, 10, 420], 100], [48, 703, 0]),\n  ('regression rested drain #2', [48, 108, [300, 300, 99, 86, 300], 30], [49, 183, 0]),\n  ('partial repair boundary #1', [30, 20, [50, 100, 10, 10], 1000], [30, 360, 830]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 56, [99], 100], [50, 56, 100]),\n  ('control #2', [50, 12, [2000, 50, 300, 50], 30], [50, 12, 30])],\n [('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),\n  ('regression rested drain #1', [48, 123, [50, 10, 420], 100], [48, 703, 0]),\n  ('fault site rested drain #1', [5, 79, [300], 0], [6, 199, 0]),\n  ('partial repair boundary #1', [30, 20, [50, 100, 10, 10], 1000], [30, 360, 830]),\n  ('regression rested drain #2', [1, 37, [100, 100, 2000], 1000], [15, 17, 0]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 12, [2000, 50, 300, 50], 30], [50, 12, 30]),\n  ('control #2', [50, 44, [10], 100], [50, 44, 100])],\n [('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),\n  ('fault site rested drain #1', [10, 7, [300, 50, 99, 100], 0], [11, 276, 0]),\n  ('regression rested drain #1', [48, 108, [300, 300, 99, 86, 300], 30], [49, 183, 0]),\n  ('partial repair boundary #1', [1, 15, [100], 100], [2, 115, 0]),\n  ('partial repair boundary #2', [48, 26, [100, 99], 1000], [48, 424, 801]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 110, [50, 10], 0], [50, 110, 0]),\n  ('control #2', [50, 62, [300, 2000, 300], 100], [50, 62, 100])],\n [('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),\n  ('fault site rested drain #1', [5, 79, [100, 10, 2000], 0], [13, 189, 0]),\n  ('fault site rested drain #2', [29, 125, [2000], 0], [32, 85, 0]),\n  ('regression rested drain #1', [5, 102, [50, 100], 30], [6, 102, 0]),\n  ('regression rested drain #2', [5, 92, [179, 50, 437, 100], 155], [9, 173, 0]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 124, [100, 300, 2000, 415], 1000], [50, 124, 1000]),\n  ('control #2', [50, 85, [10, 207, 99], 0], [50, 85, 0])],\n [('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),\n  ('fault site rested drain #1', [30, 122, [50, 10, 300, 50, 100], 0], [30, 632, 0]),\n  ('regression rested drain #1', [1, 37, [100, 100, 2000], 1000], [15, 17, 0]),\n  ('regression rested drain #2', [1, 19, [50, 2000, 50], 1000], [14, 259, 0]),\n  ('regression rested drain #3', [30, 136, [2000, 100], 1000], [34, 396, 0]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 29, [10, 249, 50, 100], 0], [50, 29, 0]),\n  ('control #2', [50, 145, [10], 80], [50, 145, 80])]]\nfor label, args, expected in cases[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":"2b097a13be560858224eed357bb2d9e317f34a3b72cd0608ac26301dc64f0fb4","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(level, xp, gains, rested):\n    for g in gains:\n        if level >= 50:\n            break\n        bonus = min(g, rested)\n        rested -= bonus\n        xp += g + bonus\n        while level < 50 and xp >= 80 + 20 * level:\n            xp -= 80 + 20 * level\n            level += 1\n        if level >= 50:\n            xp = 0\n    return [level, xp, rested]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),\n  ('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),\n  ('regression rested drain #1', [48, 123, [50, 10, 420], 100], [48, 703, 0]),\n  ('regression rested drain #2', [48, 108, [300, 300, 99, 86, 300], 30], [49, 183, 0]),\n  ('partial repair boundary #1', [30, 20, [50, 100, 10, 10], 1000], [30, 360, 830]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 56, [99], 100], [50, 56, 100]),\n  ('control #2', [50, 12, [2000, 50, 300, 50], 30], [50, 12, 30])],\n [('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),\n  ('regression rested drain #1', [48, 123, [50, 10, 420], 100], [48, 703, 0]),\n  ('fault site rested drain #1', [5, 79, [300], 0], [6, 199, 0]),\n  ('partial repair boundary #1', [30, 20, [50, 100, 10, 10], 1000], [30, 360, 830]),\n  ('regression rested drain #2', [1, 37, [100, 100, 2000], 1000], [15, 17, 0]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 12, [2000, 50, 300, 50], 30], [50, 12, 30]),\n  ('control #2', [50, 44, [10], 100], [50, 44, 100])],\n [('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),\n  ('fault site rested drain #1', [10, 7, [300, 50, 99, 100], 0], [11, 276, 0]),\n  ('regression rested drain #1', [48, 108, [300, 300, 99, 86, 300], 30], [49, 183, 0]),\n  ('partial repair boundary #1', [1, 15, [100], 100], [2, 115, 0]),\n  ('partial repair boundary #2', [48, 26, [100, 99], 1000], [48, 424, 801]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 110, [50, 10], 0], [50, 110, 0]),\n  ('control #2', [50, 62, [300, 2000, 300], 100], [50, 62, 100])],\n [('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),\n  ('fault site rested drain #1', [5, 79, [100, 10, 2000], 0], [13, 189, 0]),\n  ('fault site rested drain #2', [29, 125, [2000], 0], [32, 85, 0]),\n  ('regression rested drain #1', [5, 102, [50, 100], 30], [6, 102, 0]),\n  ('regression rested drain #2', [5, 92, [179, 50, 437, 100], 155], [9, 173, 0]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 124, [100, 300, 2000, 415], 1000], [50, 124, 1000]),\n  ('control #2', [50, 85, [10, 207, 99], 0], [50, 85, 0])],\n [('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),\n  ('fault site rested drain #1', [30, 122, [50, 10, 300, 50, 100], 0], [30, 632, 0]),\n  ('regression rested drain #1', [1, 37, [100, 100, 2000], 1000], [15, 17, 0]),\n  ('regression rested drain #2', [1, 19, [50, 2000, 50], 1000], [14, 259, 0]),\n  ('regression rested drain #3', [30, 136, [2000, 100], 1000], [34, 396, 0]),\n  ('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),\n  ('control #1', [50, 29, [10, 249, 50, 100], 0], [50, 29, 0]),\n  ('control #2', [50, 145, [10], 80], [50, 145, 80])]]\nfor label, args, expected in cases[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":"Deterministic toy contract stipulated for this model; integer or exact arithmetic only, not a reproduction of any specific game engine. 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-game-economy-crafting-balance-rested-xp-rested-drain","generated_at":"2026-09-29T14:50:48.351332+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Game economies leak or destroy currency when one crafting or pricing rule is off by one boundary, rounding stage or state update; the defect is observable in exact integer outcomes.","repair":"Restore `rested -= bonus` at the rested drain step.","root_cause":"The pool is reduced by the base gain rather than the bonus actually granted.","sha256":"de317e31c7b86adf4733ed52744a027a26991c51f25ac565c81c73b007fbc2b6","title":"Crafting XP with rested pool: Rested pool drains by the base gain · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":37.561,"exit_code":1,"observations":[{"actual":[3,80,0],"check":"multi-level gain #1","expected":[3,80,0],"passed":true},{"actual":[11,0,0],"check":"exact threshold #1","expected":[11,0,0],"passed":true},{"actual":[48,653,0],"check":"regression rested drain #1","expected":[48,703,0],"passed":false},{"actual":[49,183,-30],"check":"regression rested drain #2","expected":[49,183,0],"passed":false},{"actual":[30,360,660],"check":"partial repair boundary #1","expected":[30,360,830],"passed":false},{"actual":[50,0,40],"check":"gain at cap keeps rested #1","expected":[50,0,40],"passed":true},{"actual":[50,56,100],"check":"control #1","expected":[50,56,100],"passed":true},{"actual":[50,12,30],"check":"control #2","expected":[50,12,30],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"multi-level gain #1\", \"actual\": [3, 80, 0], \"expected\": [3, 80, 0], \"passed\": true}, {\"check\": \"exact threshold #1\", \"actual\": [11, 0, 0], \"expected\": [11, 0, 0], \"passed\": true}, {\"check\": \"regression rested drain #1\", \"actual\": [48, 653, 0], \"expected\": [48, 703, 0], \"passed\": false}, {\"check\": \"regression rested drain #2\", \"actual\": [49, 183, -30], \"expected\": [49, 183, 0], \"passed\": false}, {\"check\": \"partial repair boundary #1\", \"actual\": [30, 360, 660], \"expected\": [30, 360, 830], \"passed\": false}, {\"check\": \"gain at cap keeps rested #1\", \"actual\": [50, 0, 40], \"expected\": [50, 0, 40], \"passed\": true}, {\"check\": \"control #1\", \"actual\": [50, 56, 100], \"expected\": [50, 56, 100], \"passed\": true}, {\"check\": \"control #2\", \"actual\": [50, 12, 30], \"expected\": [50, 12, 30], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":38.208,"exit_code":1,"observations":[{"actual":[3,80,-300],"check":"multi-level gain #1","expected":[3,80,0],"passed":false},{"actual":[11,0,-280],"check":"exact threshold #1","expected":[11,0,0],"passed":false},{"actual":[48,703,-380],"check":"regression rested drain #1","expected":[48,703,0],"passed":false},{"actual":[48,-1041,-1055],"check":"regression rested drain #2","expected":[49,183,0],"passed":false},{"actual":[30,360,830],"check":"partial repair boundary #1","expected":[30,360,830],"passed":true},{"actual":[50,0,40],"check":"gain at cap keeps rested #1","expected":[50,0,40],"passed":true},{"actual":[50,56,100],"check":"control #1","expected":[50,56,100],"passed":true},{"actual":[50,12,30],"check":"control #2","expected":[50,12,30],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"multi-level gain #1\", \"actual\": [3, 80, -300], \"expected\": [3, 80, 0], \"passed\": false}, {\"check\": \"exact threshold #1\", \"actual\": [11, 0, -280], \"expected\": [11, 0, 0], \"passed\": false}, {\"check\": \"regression rested drain #1\", \"actual\": [48, 703, -380], \"expected\": [48, 703, 0], \"passed\": false}, {\"check\": \"regression rested drain #2\", \"actual\": [48, -1041, -1055], \"expected\": [49, 183, 0], \"passed\": false}, {\"check\": \"partial repair boundary #1\", \"actual\": [30, 360, 830], \"expected\": [30, 360, 830], \"passed\": true}, {\"check\": \"gain at cap keeps rested #1\", \"actual\": [50, 0, 40], \"expected\": [50, 0, 40], \"passed\": true}, {\"check\": \"control #1\", \"actual\": [50, 56, 100], \"expected\": [50, 56, 100], \"passed\": true}, {\"check\": \"control #2\", \"actual\": [50, 12, 30], \"expected\": [50, 12, 30], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.393,"exit_code":0,"observations":[{"actual":[3,80,0],"check":"multi-level gain #1","expected":[3,80,0],"passed":true},{"actual":[11,0,0],"check":"exact threshold #1","expected":[11,0,0],"passed":true},{"actual":[48,703,0],"check":"regression rested drain #1","expected":[48,703,0],"passed":true},{"actual":[49,183,0],"check":"regression rested drain #2","expected":[49,183,0],"passed":true},{"actual":[30,360,830],"check":"partial repair boundary #1","expected":[30,360,830],"passed":true},{"actual":[50,0,40],"check":"gain at cap keeps rested #1","expected":[50,0,40],"passed":true},{"actual":[50,56,100],"check":"control #1","expected":[50,56,100],"passed":true},{"actual":[50,12,30],"check":"control #2","expected":[50,12,30],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"multi-level gain #1\", \"actual\": [3, 80, 0], \"expected\": [3, 80, 0], \"passed\": true}, {\"check\": \"exact threshold #1\", \"actual\": [11, 0, 0], \"expected\": [11, 0, 0], \"passed\": true}, {\"check\": \"regression rested drain #1\", \"actual\": [48, 703, 0], \"expected\": [48, 703, 0], \"passed\": true}, {\"check\": \"regression rested drain #2\", \"actual\": [49, 183, 0], \"expected\": [49, 183, 0], \"passed\": true}, {\"check\": \"partial repair boundary #1\", \"actual\": [30, 360, 830], \"expected\": [30, 360, 830], \"passed\": true}, {\"check\": \"gain at cap keeps rested #1\", \"actual\": [50, 0, 40], \"expected\": [50, 0, 40], \"passed\": true}, {\"check\": \"control #1\", \"actual\": [50, 56, 100], \"expected\": [50, 56, 100], \"passed\": true}, {\"check\": \"control #2\", \"actual\": [50, 12, 30], \"expected\": [50, 12, 30], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}