{"abstract":"A home -1.5 bet wins when the home side loses.","category":"Betting odds conversion","checks":10,"contract":"Asian handicap bet on the home side. line is a multiple of 0.25 (else \"invalid line\"). Whole and half lines are a single bet; quarter lines split the stake equally between line - 0.25 and line + 0.25. Each part: margin = home_goals - away_goals + part_line; positive wins stake_part * price, zero refunds stake_part, negative loses. Return [total return in cents rounded down, label] where the label is win, half-win, push, half-lose or lose from the summed part outcomes.","contract_signature":"line, home_goals, away_goals, stake_cents, price","evaluation_group":"w2-odds-conversion-asian-handicap-settlement","failed_approach":"Computing the away margin plus the line settles the away bet, not the home bet.","family":"w2-odds-conversion-asian-handicap-settlement-line-orientation","id":"FA-84521","implementations":{"attempt":{"sha256":"38422eef802e81e2686dbe578169a1d46ae93ae9ba42a6b32bf4207503ef52f8","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nfrom fractions import Fraction\nimport math\nN = 1\nobservations = []\ndef solve(line, home_goals, away_goals, stake_cents, price):\n    L = Fraction(line)\n    if (L * 4).denominator != 1:\n        return 'invalid line'\n    if (L * 2).denominator == 1:\n        parts = [L]\n    else:\n        parts = [L - Fraction(1, 4), L + Fraction(1, 4)]\n    d = Fraction(price)\n    share = Fraction(stake_cents, len(parts))\n    ret = Fraction(0)\n    res = []\n    for p in parts:\n        m = away_goals - home_goals + p\n        if m > 0:\n            ret += share * d\n            res.append(1)\n        elif m == 0:\n            ret += share\n            res.append(0)\n        else:\n            res.append(-1)\n    score = sum(res) * 2 // len(parts)\n    label = {2: 'win', 1: 'half-win', 0: 'push', -1: 'half-lose', -2: 'lose'}[score]\n    return [math.floor(ret), label]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ndef run(args):\n    try:\n        return solve(*args)\n    except Exception as exc:\n        return 'raised ' + type(exc).__name__\ncases = [[('control half line win', ('-0.5', 1, 0, 1000, '1.90'), [1900, 'win']),\n  ('boundary whole line push', ('-1', 2, 1, 1000, '1.90'), [1000, 'push']),\n  ('boundary quarter half-lose', ('-0.25', 1, 1, 1000, '1.90'), [500, 'half-lose']),\n  ('boundary quarter half-win', ('-0.75', 1, 0, 1000, '2.00'), [1500, 'half-win']),\n  ('control lose', ('+0.5', 0, 2, 1000, '1.90'), [0, 'lose']),\n  ('boundary off-grid line', ('-0.3', 1, 0, 1000, '1.90'), 'invalid line'),\n  ('regression: line orientation', ('+0.75', 0, 4, 999, '1.90'), [0, 'lose']),\n  ('regression: line orientation', ('-1.5', 2, 3, 500, '2.00'), [0, 'lose']),\n  ('variant scenario 1', ('-0.3', 0, 0, 999, '1.90'), 'invalid line'),\n  ('variant scenario 2', ('-0.3', 2, 0, 250, '2.00'), 'invalid line')],\n [('control half line win', ('-0.5', 1, 0, 1000, '1.90'), [1900, 'win']),\n  ('boundary whole line push', ('-1', 2, 1, 1000, '1.90'), [1000, 'push']),\n  ('boundary quarter half-lose', ('-0.25', 1, 1, 1000, '1.90'), [500, 'half-lose']),\n  ('boundary quarter half-win', ('-0.75', 1, 0, 1000, '2.00'), [1500, 'half-win']),\n  ('control lose', ('+0.5', 0, 2, 1000, '1.90'), [0, 'lose']),\n  ('boundary off-grid line', ('-0.3', 1, 0, 1000, '1.90'), 'invalid line'),\n  ('regression: line orientation', ('-0.25', 4, 0, 999, '1.90'), [1898, 'win']),\n  ('regression: line orientation', ('-0.25', 3, 3, 500, '2.00'), [250, 'half-lose']),\n  ('variant scenario 1', ('+1.25', 1, 3, 999, '2.05'), [0, 'lose']),\n  ('variant scenario 2', ('-0.5', 3, 4, 1000, '2.05'), [0, 'lose'])],\n [('control half line win', ('-0.5', 1, 0, 1000, '1.90'), [1900, 'win']),\n  ('boundary whole line push', ('-1', 2, 1, 1000, '1.90'), [1000, 'push']),\n  ('boundary quarter half-lose', ('-0.25', 1, 1, 1000, '1.90'), [500, 'half-lose']),\n  ('boundary quarter half-win', ('-0.75', 1, 0, 1000, '2.00'), [1500, 'half-win']),\n  ('control lose', ('+0.5', 0, 2, 1000, '1.90'), [0, 'lose']),\n  ('boundary off-grid line', ('-0.3', 1, 0, 1000, '1.90'), 'invalid line'),\n  ('regression: line orientation', ('+0.25', 0, 0, 999, '1.85'), [1423, 'half-win']),\n  ('regression: line orientation', ('+0.75', 2, 4, 1000, '2.00'), [0, 'lose']),\n  ('variant scenario 1', ('-0.5', 1, 0, 250, '2.00'), [500, 'win']),\n  ('variant scenario 2', ('-1.5', 4, 0, 250, '2.00'), [500, 'win'])],\n [('control half line win', ('-0.5', 1, 0, 1000, '1.90'), [1900, 'win']),\n  ('boundary whole line push', ('-1', 2, 1, 1000, '1.90'), [1000, 'push']),\n  ('boundary quarter half-lose', ('-0.25', 1, 1, 1000, '1.90'), [500, 'half-lose']),\n  ('boundary quarter half-win', ('-0.75', 1, 0, 1000, '2.00'), [1500, 'half-win']),\n  ('control lose', ('+0.5', 0, 2, 1000, '1.90'), [0, 'lose']),\n  ('boundary off-grid line', ('-0.3', 1, 0, 1000, '1.90'), 'invalid line'),\n  ('regression: line orientation', ('-0.25', 4, 0, 250, '2.05'), [512, 'win']),\n  ('regression: line orientation', ('-1.75', 2, 3, 999, '1.85'), [0, 'lose']),\n  ('variant scenario 1', ('-0.3', 1, 2, 250, '1.90'), 'invalid line'),\n  ('variant scenario 2', ('+0.25', 4, 3, 250, '2.05'), [512, 'win'])],\n [('control half line win', ('-0.5', 1, 0, 1000, '1.90'), [1900, 'win']),\n  ('boundary whole line push', ('-1', 2, 1, 1000, '1.90'), [1000, 'push']),\n  ('boundary quarter half-lose', ('-0.25', 1, 1, 1000, '1.90'), [500, 'half-lose']),\n  ('boundary quarter half-win', ('-0.75', 1, 0, 1000, '2.00'), [1500, 'half-win']),\n  ('control lose', ('+0.5', 0, 2, 1000, '1.90'), [0, 'lose']),\n  ('boundary off-grid line', ('-0.3', 1, 0, 1000, '1.90'), 'invalid line'),\n  ('regression: line orientation', ('+0.5', 4, 2, 500, '2.00'), [1000, 'win']),\n  ('regression: line orientation', ('+0.75', 4, 3, 250, '1.85'), [462, 'win']),\n  ('variant scenario 1', ('+0.75', 2, 0, 1000, '1.90'), [1900, 'win']),\n  ('variant scenario 2', ('-1', 0, 3, 250, '2.05'), [0, 'lose'])]]\nfor label, args, expected in cases[N - 1]:\n    check(label, run(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":"bc968c338e097b1ded8b25f5af8c414ed846872359e1e5b424548b91912ae279","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nfrom fractions import Fraction\nimport math\nN = 1\nobservations = []\ndef solve(line, home_goals, away_goals, stake_cents, price):\n    L = Fraction(line)\n    if (L * 4).denominator != 1:\n        return 'invalid line'\n    if (L * 2).denominator == 1:\n        parts = [L]\n    else:\n        parts = [L - Fraction(1, 4), L + Fraction(1, 4)]\n    d = Fraction(price)\n    share = Fraction(stake_cents, len(parts))\n    ret = Fraction(0)\n    res = []\n    for p in parts:\n        m = home_goals - away_goals - p\n        if m > 0:\n            ret += share * d\n            res.append(1)\n        elif m == 0:\n            ret += share\n            res.append(0)\n        else:\n            res.append(-1)\n    score = sum(res) * 2 // len(parts)\n    label = {2: 'win', 1: 'half-win', 0: 'push', -1: 'half-lose', -2: 'lose'}[score]\n    return [math.floor(ret), label]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ndef run(args):\n    try:\n        return solve(*args)\n    except Exception as exc:\n        return 'raised ' + type(exc).__name__\ncases = [[('control half line win', ('-0.5', 1, 0, 1000, '1.90'), [1900, 'win']),\n  ('boundary whole line push', ('-1', 2, 1, 1000, '1.90'), [1000, 'push']),\n  ('boundary quarter half-lose', ('-0.25', 1, 1, 1000, '1.90'), [500, 'half-lose']),\n  ('boundary quarter half-win', ('-0.75', 1, 0, 1000, '2.00'), [1500, 'half-win']),\n  ('control lose', ('+0.5', 0, 2, 1000, '1.90'), [0, 'lose']),\n  ('boundary off-grid line', ('-0.3', 1, 0, 1000, '1.90'), 'invalid line'),\n  ('regression: line orientation', ('+0.75', 0, 4, 999, '1.90'), [0, 'lose']),\n  ('regression: line orientation', ('-1.5', 2, 3, 500, '2.00'), [0, 'lose']),\n  ('variant scenario 1', ('-0.3', 0, 0, 999, '1.90'), 'invalid line'),\n  ('variant scenario 2', ('-0.3', 2, 0, 250, '2.00'), 'invalid line')],\n [('control half line win', ('-0.5', 1, 0, 1000, '1.90'), [1900, 'win']),\n  ('boundary whole line push', ('-1', 2, 1, 1000, '1.90'), [1000, 'push']),\n  ('boundary quarter half-lose', ('-0.25', 1, 1, 1000, '1.90'), [500, 'half-lose']),\n  ('boundary quarter half-win', ('-0.75', 1, 0, 1000, '2.00'), [1500, 'half-win']),\n  ('control lose', ('+0.5', 0, 2, 1000, '1.90'), [0, 'lose']),\n  ('boundary off-grid line', ('-0.3', 1, 0, 1000, '1.90'), 'invalid line'),\n  ('regression: line orientation', ('-0.25', 4, 0, 999, '1.90'), [1898, 'win']),\n  ('regression: line orientation', ('-0.25', 3, 3, 500, '2.00'), [250, 'half-lose']),\n  ('variant scenario 1', ('+1.25', 1, 3, 999, '2.05'), [0, 'lose']),\n  ('variant scenario 2', ('-0.5', 3, 4, 1000, '2.05'), [0, 'lose'])],\n [('control half line win', ('-0.5', 1, 0, 1000, '1.90'), [1900, 'win']),\n  ('boundary whole line push', ('-1', 2, 1, 1000, '1.90'), [1000, 'push']),\n  ('boundary quarter half-lose', ('-0.25', 1, 1, 1000, '1.90'), [500, 'half-lose']),\n  ('boundary quarter half-win', ('-0.75', 1, 0, 1000, '2.00'), [1500, 'half-win']),\n  ('control lose', ('+0.5', 0, 2, 1000, '1.90'), [0, 'lose']),\n  ('boundary off-grid line', ('-0.3', 1, 0, 1000, '1.90'), 'invalid line'),\n  ('regression: line orientation', ('+0.25', 0, 0, 999, '1.85'), [1423, 'half-win']),\n  ('regression: line orientation', ('+0.75', 2, 4, 1000, '2.00'), [0, 'lose']),\n  ('variant scenario 1', ('-0.5', 1, 0, 250, '2.00'), [500, 'win']),\n  ('variant scenario 2', ('-1.5', 4, 0, 250, '2.00'), [500, 'win'])],\n [('control half line win', ('-0.5', 1, 0, 1000, '1.90'), [1900, 'win']),\n  ('boundary whole line push', ('-1', 2, 1, 1000, '1.90'), [1000, 'push']),\n  ('boundary quarter half-lose', ('-0.25', 1, 1, 1000, '1.90'), [500, 'half-lose']),\n  ('boundary quarter half-win', ('-0.75', 1, 0, 1000, '2.00'), [1500, 'half-win']),\n  ('control lose', ('+0.5', 0, 2, 1000, '1.90'), [0, 'lose']),\n  ('boundary off-grid line', ('-0.3', 1, 0, 1000, '1.90'), 'invalid line'),\n  ('regression: line orientation', ('-0.25', 4, 0, 250, '2.05'), [512, 'win']),\n  ('regression: line orientation', ('-1.75', 2, 3, 999, '1.85'), [0, 'lose']),\n  ('variant scenario 1', ('-0.3', 1, 2, 250, '1.90'), 'invalid line'),\n  ('variant scenario 2', ('+0.25', 4, 3, 250, '2.05'), [512, 'win'])],\n [('control half line win', ('-0.5', 1, 0, 1000, '1.90'), [1900, 'win']),\n  ('boundary whole line push', ('-1', 2, 1, 1000, '1.90'), [1000, 'push']),\n  ('boundary quarter half-lose', ('-0.25', 1, 1, 1000, '1.90'), [500, 'half-lose']),\n  ('boundary quarter half-win', ('-0.75', 1, 0, 1000, '2.00'), [1500, 'half-win']),\n  ('control lose', ('+0.5', 0, 2, 1000, '1.90'), [0, 'lose']),\n  ('boundary off-grid line', ('-0.3', 1, 0, 1000, '1.90'), 'invalid line'),\n  ('regression: line orientation', ('+0.5', 4, 2, 500, '2.00'), [1000, 'win']),\n  ('regression: line orientation', ('+0.75', 4, 3, 250, '1.85'), [462, 'win']),\n  ('variant scenario 1', ('+0.75', 2, 0, 1000, '1.90'), [1900, 'win']),\n  ('variant scenario 2', ('-1', 0, 3, 250, '2.05'), [0, 'lose'])]]\nfor label, args, expected in cases[N - 1]:\n    check(label, run(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 toy contract stated in the contract field; not a claim of conformance with any operator, exchange or regulator rule set. 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-odds-conversion-asian-handicap-settlement-line-orientation","generated_at":"2026-09-29T14:50:31.759073+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Asian handicap settlement with split quarter lines is a common source of payout disputes.","root_cause":"The handicap is subtracted from the home margin.","sha256":"ba767cb7173b886977c3fd0d5926aa4b4d373f930cd87de8b8bd407cda55351c","title":"Handicap applied to the wrong side · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verified":true,"visibility":"public","verification":{"attempt":{"elapsed_ms":44.516,"exit_code":1,"observations":[{"actual":[0,"lose"],"check":"control half line win","expected":[1900,"win"],"passed":false},{"actual":[0,"lose"],"check":"boundary whole line push","expected":[1000,"push"],"passed":false},{"actual":[500,"half-lose"],"check":"boundary quarter half-lose","expected":[500,"half-lose"],"passed":true},{"actual":[0,"lose"],"check":"boundary quarter half-win","expected":[1500,"half-win"],"passed":false},{"actual":[1900,"win"],"check":"control lose","expected":[0,"lose"],"passed":false},{"actual":"invalid line","check":"boundary off-grid line","expected":"invalid line","passed":true},{"actual":[1898,"win"],"check":"regression: line orientation","expected":[0,"lose"],"passed":false},{"actual":[0,"lose"],"check":"regression: line orientation","expected":[0,"lose"],"passed":true},{"actual":"invalid line","check":"variant scenario 1","expected":"invalid line","passed":true},{"actual":"invalid line","check":"variant scenario 2","expected":"invalid line","passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"control half line win\", \"actual\": [0, \"lose\"], \"expected\": [1900, \"win\"], \"passed\": false}, {\"check\": \"boundary whole line push\", \"actual\": [0, \"lose\"], \"expected\": [1000, \"push\"], \"passed\": false}, {\"check\": \"boundary quarter half-lose\", \"actual\": [500, \"half-lose\"], \"expected\": [500, \"half-lose\"], \"passed\": true}, {\"check\": \"boundary quarter half-win\", \"actual\": [0, \"lose\"], \"expected\": [1500, \"half-win\"], \"passed\": false}, {\"check\": \"control lose\", \"actual\": [1900, \"win\"], \"expected\": [0, \"lose\"], \"passed\": false}, {\"check\": \"boundary off-grid line\", \"actual\": \"invalid line\", \"expected\": \"invalid line\", \"passed\": true}, {\"check\": \"regression: line orientation\", \"actual\": [1898, \"win\"], \"expected\": [0, \"lose\"], \"passed\": false}, {\"check\": \"regression: line orientation\", \"actual\": [0, \"lose\"], \"expected\": [0, \"lose\"], \"passed\": true}, {\"check\": \"variant scenario 1\", \"actual\": \"invalid line\", \"expected\": \"invalid line\", \"passed\": true}, {\"check\": \"variant scenario 2\", \"actual\": \"invalid line\", \"expected\": \"invalid line\", \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":43.213,"exit_code":1,"observations":[{"actual":[1900,"win"],"check":"control half line win","expected":[1900,"win"],"passed":true},{"actual":[1900,"win"],"check":"boundary whole line push","expected":[1000,"push"],"passed":false},{"actual":[1450,"half-win"],"check":"boundary quarter half-lose","expected":[500,"half-lose"],"passed":false},{"actual":[2000,"win"],"check":"boundary quarter half-win","expected":[1500,"half-win"],"passed":false},{"actual":[0,"lose"],"check":"control lose","expected":[0,"lose"],"passed":true},{"actual":"invalid line","check":"boundary off-grid line","expected":"invalid line","passed":true},{"actual":[0,"lose"],"check":"regression: line orientation","expected":[0,"lose"],"passed":true},{"actual":[1000,"win"],"check":"regression: line orientation","expected":[0,"lose"],"passed":false},{"actual":"invalid line","check":"variant scenario 1","expected":"invalid line","passed":true},{"actual":"invalid line","check":"variant scenario 2","expected":"invalid line","passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"control half line win\", \"actual\": [1900, \"win\"], \"expected\": [1900, \"win\"], \"passed\": true}, {\"check\": \"boundary whole line push\", \"actual\": [1900, \"win\"], \"expected\": [1000, \"push\"], \"passed\": false}, {\"check\": \"boundary quarter half-lose\", \"actual\": [1450, \"half-win\"], \"expected\": [500, \"half-lose\"], \"passed\": false}, {\"check\": \"boundary quarter half-win\", \"actual\": [2000, \"win\"], \"expected\": [1500, \"half-win\"], \"passed\": false}, {\"check\": \"control lose\", \"actual\": [0, \"lose\"], \"expected\": [0, \"lose\"], \"passed\": true}, {\"check\": \"boundary off-grid line\", \"actual\": \"invalid line\", \"expected\": \"invalid line\", \"passed\": true}, {\"check\": \"regression: line orientation\", \"actual\": [0, \"lose\"], \"expected\": [0, \"lose\"], \"passed\": true}, {\"check\": \"regression: line orientation\", \"actual\": [1000, \"win\"], \"expected\": [0, \"lose\"], \"passed\": false}, {\"check\": \"variant scenario 1\", \"actual\": \"invalid line\", \"expected\": \"invalid line\", \"passed\": true}, {\"check\": \"variant scenario 2\", \"actual\": \"invalid line\", \"expected\": \"invalid line\", \"passed\": true}], \"passed\": false}\n"}},"member_only":{"stages":["fixed"],"fields":["implementations.fixed","verification.fixed","harness","repair"],"note":"The verified repair, its recorded checks, the repair description, and the scoring harness are available to members."}}