{"abstract":"Prices fall one coin more than the floor rule.","category":"Game economy crafting balance","checks":8,"contract":"If target <= 0 the price is only clamped to [floor, ceiling]. If sold > target: pct = min(20, floor((sold-target)*100/target)), step = floor(price*pct/100) but at least 1 when pct > 0, new = price + step. If sold < target: pct = min(15, floor((target-sold)*100/target)), new = price - floor(price*pct/100). Otherwise unchanged. Result clamped to [floor, ceiling].","evaluation_group":"w2-game-economy-crafting-balance-market-rebalance","failed_approach":"Rounding the decrease still over-drops when the fraction is at least one half.","family":"w2-game-economy-crafting-balance-market-rebalance-decrease-rounding","id":"FA-86261","implementations":{"attempt":{"sha256":"5baf08d329cf8e0be263aa3c337e5c5c28f0dadc65d9a7276bb792251224d101","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(price, sold, target, floor, ceiling):\n    if target <= 0:\n        return min(max(price, floor), ceiling)\n    if sold > target:\n        pct = min(20, (sold - target) * 100 // target)\n        step = price * pct // 100\n        if pct > 0:\n            step = max(step, 1)\n        new = price + step\n    elif sold < target:\n        pct = min(15, (target - sold) * 100 // target)\n        new = price - round(price * pct / 100)\n    else:\n        new = price\n    return min(max(new, floor), ceiling)\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('regression decrease rounding #1', [50, 42, 70, 38, 107], 43),\n  ('regression decrease rounding #2', [99, 39, 40, 15, 1103], 98),\n  ('regression decrease rounding #3', [99, 0, 5, 18, 422], 85),\n  ('regression decrease rounding #4', [50, 4, 5, 36, 1502], 43),\n  ('no target listed #1', [5, 3, 0, 10, 50], 10),\n  ('cheap item rises one #1', [3, 13, 10, 1, 100], 4),\n  ('crash capped at 15 #1', [1000, 0, 40, 1, 5000], 850),\n  ('control #1', [99, 1188, 396, 6, 782], 118)],\n [('regression decrease rounding #1', [99, 0, 5, 18, 422], 85),\n  ('regression decrease rounding #2', [50, 4, 5, 36, 1502], 43),\n  ('regression decrease rounding #3', [873, 0, 1, 38, 806], 743),\n  ('regression decrease rounding #4', [99, 39, 40, 28, 329], 98),\n  ('crash capped at 15 #1', [1000, 0, 40, 1, 5000], 850),\n  ('no target listed #1', [5, 3, 0, 10, 50], 10),\n  ('control #1', [99, 1188, 396, 6, 782], 118),\n  ('control #2', [9, 0, 1, 47, 499], 47)],\n [('regression decrease rounding #1', [873, 0, 1, 38, 806], 743),\n  ('fault site decrease rounding #1', [50, 50, 51, 3, 1314], 50),\n  ('regression decrease rounding #2', [99, 39, 40, 28, 329], 98),\n  ('regression decrease rounding #3', [99, 0, 1, 41, 274], 85),\n  ('cheap item rises one #1', [3, 13, 10, 1, 100], 4),\n  ('crash capped at 15 #1', [1000, 0, 40, 1, 5000], 850),\n  ('control #1', [9, 0, 1, 47, 499], 47),\n  ('control #2', [1000, 0, 0, 7, 47], 47)],\n [('regression decrease rounding #1', [99, 39, 40, 28, 329], 98),\n  ('fault site decrease rounding #1', [675, 0, 41, 20, 744], 574),\n  ('regression decrease rounding #2', [99, 0, 1, 41, 274], 85),\n  ('regression decrease rounding #3', [99, 0, 897, 18, 606], 85),\n  ('no target listed #1', [5, 3, 0, 10, 50], 10),\n  ('cheap item rises one #1', [3, 13, 10, 1, 100], 4),\n  ('control #1', [736, 68, 66, 28, 100], 100),\n  ('control #2', [3, 75, 76, 12, 1170], 12)],\n [('regression decrease rounding #1', [99, 0, 1, 41, 274], 85),\n  ('regression decrease rounding #2', [99, 0, 897, 18, 606], 85),\n  ('regression decrease rounding #3', [99, 4, 5, 14, 1130], 85),\n  ('regression decrease rounding #4', [99, 0, 1, 13, 99], 85),\n  ('crash capped at 15 #1', [1000, 0, 40, 1, 5000], 850),\n  ('no target listed #1', [5, 3, 0, 10, 50], 10),\n  ('control #1', [1000, 5, 5, 37, 1007], 1000),\n  ('control #2', [50, 11, 10, 38, 410], 55)]]\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":"9b19d2e6b11ed50e07c210db042223a56264f61135adcb9ced1e76f967b28334","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(price, sold, target, floor, ceiling):\n    if target <= 0:\n        return min(max(price, floor), ceiling)\n    if sold > target:\n        pct = min(20, (sold - target) * 100 // target)\n        step = price * pct // 100\n        if pct > 0:\n            step = max(step, 1)\n        new = price + step\n    elif sold < target:\n        pct = min(15, (target - sold) * 100 // target)\n        new = price * (100 - pct) // 100\n    else:\n        new = price\n    return min(max(new, floor), ceiling)\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('regression decrease rounding #1', [50, 42, 70, 38, 107], 43),\n  ('regression decrease rounding #2', [99, 39, 40, 15, 1103], 98),\n  ('regression decrease rounding #3', [99, 0, 5, 18, 422], 85),\n  ('regression decrease rounding #4', [50, 4, 5, 36, 1502], 43),\n  ('no target listed #1', [5, 3, 0, 10, 50], 10),\n  ('cheap item rises one #1', [3, 13, 10, 1, 100], 4),\n  ('crash capped at 15 #1', [1000, 0, 40, 1, 5000], 850),\n  ('control #1', [99, 1188, 396, 6, 782], 118)],\n [('regression decrease rounding #1', [99, 0, 5, 18, 422], 85),\n  ('regression decrease rounding #2', [50, 4, 5, 36, 1502], 43),\n  ('regression decrease rounding #3', [873, 0, 1, 38, 806], 743),\n  ('regression decrease rounding #4', [99, 39, 40, 28, 329], 98),\n  ('crash capped at 15 #1', [1000, 0, 40, 1, 5000], 850),\n  ('no target listed #1', [5, 3, 0, 10, 50], 10),\n  ('control #1', [99, 1188, 396, 6, 782], 118),\n  ('control #2', [9, 0, 1, 47, 499], 47)],\n [('regression decrease rounding #1', [873, 0, 1, 38, 806], 743),\n  ('fault site decrease rounding #1', [50, 50, 51, 3, 1314], 50),\n  ('regression decrease rounding #2', [99, 39, 40, 28, 329], 98),\n  ('regression decrease rounding #3', [99, 0, 1, 41, 274], 85),\n  ('cheap item rises one #1', [3, 13, 10, 1, 100], 4),\n  ('crash capped at 15 #1', [1000, 0, 40, 1, 5000], 850),\n  ('control #1', [9, 0, 1, 47, 499], 47),\n  ('control #2', [1000, 0, 0, 7, 47], 47)],\n [('regression decrease rounding #1', [99, 39, 40, 28, 329], 98),\n  ('fault site decrease rounding #1', [675, 0, 41, 20, 744], 574),\n  ('regression decrease rounding #2', [99, 0, 1, 41, 274], 85),\n  ('regression decrease rounding #3', [99, 0, 897, 18, 606], 85),\n  ('no target listed #1', [5, 3, 0, 10, 50], 10),\n  ('cheap item rises one #1', [3, 13, 10, 1, 100], 4),\n  ('control #1', [736, 68, 66, 28, 100], 100),\n  ('control #2', [3, 75, 76, 12, 1170], 12)],\n [('regression decrease rounding #1', [99, 0, 1, 41, 274], 85),\n  ('regression decrease rounding #2', [99, 0, 897, 18, 606], 85),\n  ('regression decrease rounding #3', [99, 4, 5, 14, 1130], 85),\n  ('regression decrease rounding #4', [99, 0, 1, 13, 99], 85),\n  ('crash capped at 15 #1', [1000, 0, 40, 1, 5000], 850),\n  ('no target listed #1', [5, 3, 0, 10, 50], 10),\n  ('control #1', [1000, 5, 5, 37, 1007], 1000),\n  ('control #2', [50, 11, 10, 38, 410], 55)]]\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":"6e04f13c322f9f0f8f387ecd43103d84cddae4d343f527c3d50db83d9c6081dd","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(price, sold, target, floor, ceiling):\n    if target <= 0:\n        return min(max(price, floor), ceiling)\n    if sold > target:\n        pct = min(20, (sold - target) * 100 // target)\n        step = price * pct // 100\n        if pct > 0:\n            step = max(step, 1)\n        new = price + step\n    elif sold < target:\n        pct = min(15, (target - sold) * 100 // target)\n        new = price - price * pct // 100\n    else:\n        new = price\n    return min(max(new, floor), ceiling)\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('regression decrease rounding #1', [50, 42, 70, 38, 107], 43),\n  ('regression decrease rounding #2', [99, 39, 40, 15, 1103], 98),\n  ('regression decrease rounding #3', [99, 0, 5, 18, 422], 85),\n  ('regression decrease rounding #4', [50, 4, 5, 36, 1502], 43),\n  ('no target listed #1', [5, 3, 0, 10, 50], 10),\n  ('cheap item rises one #1', [3, 13, 10, 1, 100], 4),\n  ('crash capped at 15 #1', [1000, 0, 40, 1, 5000], 850),\n  ('control #1', [99, 1188, 396, 6, 782], 118)],\n [('regression decrease rounding #1', [99, 0, 5, 18, 422], 85),\n  ('regression decrease rounding #2', [50, 4, 5, 36, 1502], 43),\n  ('regression decrease rounding #3', [873, 0, 1, 38, 806], 743),\n  ('regression decrease rounding #4', [99, 39, 40, 28, 329], 98),\n  ('crash capped at 15 #1', [1000, 0, 40, 1, 5000], 850),\n  ('no target listed #1', [5, 3, 0, 10, 50], 10),\n  ('control #1', [99, 1188, 396, 6, 782], 118),\n  ('control #2', [9, 0, 1, 47, 499], 47)],\n [('regression decrease rounding #1', [873, 0, 1, 38, 806], 743),\n  ('fault site decrease rounding #1', [50, 50, 51, 3, 1314], 50),\n  ('regression decrease rounding #2', [99, 39, 40, 28, 329], 98),\n  ('regression decrease rounding #3', [99, 0, 1, 41, 274], 85),\n  ('cheap item rises one #1', [3, 13, 10, 1, 100], 4),\n  ('crash capped at 15 #1', [1000, 0, 40, 1, 5000], 850),\n  ('control #1', [9, 0, 1, 47, 499], 47),\n  ('control #2', [1000, 0, 0, 7, 47], 47)],\n [('regression decrease rounding #1', [99, 39, 40, 28, 329], 98),\n  ('fault site decrease rounding #1', [675, 0, 41, 20, 744], 574),\n  ('regression decrease rounding #2', [99, 0, 1, 41, 274], 85),\n  ('regression decrease rounding #3', [99, 0, 897, 18, 606], 85),\n  ('no target listed #1', [5, 3, 0, 10, 50], 10),\n  ('cheap item rises one #1', [3, 13, 10, 1, 100], 4),\n  ('control #1', [736, 68, 66, 28, 100], 100),\n  ('control #2', [3, 75, 76, 12, 1170], 12)],\n [('regression decrease rounding #1', [99, 0, 1, 41, 274], 85),\n  ('regression decrease rounding #2', [99, 0, 897, 18, 606], 85),\n  ('regression decrease rounding #3', [99, 4, 5, 14, 1130], 85),\n  ('regression decrease rounding #4', [99, 0, 1, 13, 99], 85),\n  ('crash capped at 15 #1', [1000, 0, 40, 1, 5000], 850),\n  ('no target listed #1', [5, 3, 0, 10, 50], 10),\n  ('control #1', [1000, 5, 5, 37, 1007], 1000),\n  ('control #2', [50, 11, 10, 38, 410], 55)]]\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-market-rebalance-decrease-rounding","generated_at":"2026-09-29T14:50:48.009978+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 `new = price - price * pct // 100` at the decrease rounding step.","root_cause":"The reduced price is floored, rounding the decrease up.","sha256":"fd1a6cad4d1d8025776f1075ddc9b5861c0327bbe791b5f0411683401679702d","title":"Daily market rebalance: Price drops round against the seller · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":37.829,"exit_code":1,"observations":[{"actual":42,"check":"regression decrease rounding #1","expected":43,"passed":false},{"actual":97,"check":"regression decrease rounding #2","expected":98,"passed":false},{"actual":84,"check":"regression decrease rounding #3","expected":85,"passed":false},{"actual":42,"check":"regression decrease rounding #4","expected":43,"passed":false},{"actual":10,"check":"no target listed #1","expected":10,"passed":true},{"actual":4,"check":"cheap item rises one #1","expected":4,"passed":true},{"actual":850,"check":"crash capped at 15 #1","expected":850,"passed":true},{"actual":118,"check":"control #1","expected":118,"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression decrease rounding #1\", \"actual\": 42, \"expected\": 43, \"passed\": false}, {\"check\": \"regression decrease rounding #2\", \"actual\": 97, \"expected\": 98, \"passed\": false}, {\"check\": \"regression decrease rounding #3\", \"actual\": 84, \"expected\": 85, \"passed\": false}, {\"check\": \"regression decrease rounding #4\", \"actual\": 42, \"expected\": 43, \"passed\": false}, {\"check\": \"no target listed #1\", \"actual\": 10, \"expected\": 10, \"passed\": true}, {\"check\": \"cheap item rises one #1\", \"actual\": 4, \"expected\": 4, \"passed\": true}, {\"check\": \"crash capped at 15 #1\", \"actual\": 850, \"expected\": 850, \"passed\": true}, {\"check\": \"control #1\", \"actual\": 118, \"expected\": 118, \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":39.447,"exit_code":1,"observations":[{"actual":42,"check":"regression decrease rounding #1","expected":43,"passed":false},{"actual":97,"check":"regression decrease rounding #2","expected":98,"passed":false},{"actual":84,"check":"regression decrease rounding #3","expected":85,"passed":false},{"actual":42,"check":"regression decrease rounding #4","expected":43,"passed":false},{"actual":10,"check":"no target listed #1","expected":10,"passed":true},{"actual":4,"check":"cheap item rises one #1","expected":4,"passed":true},{"actual":850,"check":"crash capped at 15 #1","expected":850,"passed":true},{"actual":118,"check":"control #1","expected":118,"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression decrease rounding #1\", \"actual\": 42, \"expected\": 43, \"passed\": false}, {\"check\": \"regression decrease rounding #2\", \"actual\": 97, \"expected\": 98, \"passed\": false}, {\"check\": \"regression decrease rounding #3\", \"actual\": 84, \"expected\": 85, \"passed\": false}, {\"check\": \"regression decrease rounding #4\", \"actual\": 42, \"expected\": 43, \"passed\": false}, {\"check\": \"no target listed #1\", \"actual\": 10, \"expected\": 10, \"passed\": true}, {\"check\": \"cheap item rises one #1\", \"actual\": 4, \"expected\": 4, \"passed\": true}, {\"check\": \"crash capped at 15 #1\", \"actual\": 850, \"expected\": 850, \"passed\": true}, {\"check\": \"control #1\", \"actual\": 118, \"expected\": 118, \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.011,"exit_code":0,"observations":[{"actual":43,"check":"regression decrease rounding #1","expected":43,"passed":true},{"actual":98,"check":"regression decrease rounding #2","expected":98,"passed":true},{"actual":85,"check":"regression decrease rounding #3","expected":85,"passed":true},{"actual":43,"check":"regression decrease rounding #4","expected":43,"passed":true},{"actual":10,"check":"no target listed #1","expected":10,"passed":true},{"actual":4,"check":"cheap item rises one #1","expected":4,"passed":true},{"actual":850,"check":"crash capped at 15 #1","expected":850,"passed":true},{"actual":118,"check":"control #1","expected":118,"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression decrease rounding #1\", \"actual\": 43, \"expected\": 43, \"passed\": true}, {\"check\": \"regression decrease rounding #2\", \"actual\": 98, \"expected\": 98, \"passed\": true}, {\"check\": \"regression decrease rounding #3\", \"actual\": 85, \"expected\": 85, \"passed\": true}, {\"check\": \"regression decrease rounding #4\", \"actual\": 43, \"expected\": 43, \"passed\": true}, {\"check\": \"no target listed #1\", \"actual\": 10, \"expected\": 10, \"passed\": true}, {\"check\": \"cheap item rises one #1\", \"actual\": 4, \"expected\": 4, \"passed\": true}, {\"check\": \"crash capped at 15 #1\", \"actual\": 850, \"expected\": 850, \"passed\": true}, {\"check\": \"control #1\", \"actual\": 118, \"expected\": 118, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}