{"abstract":"Francs paid in cash come out at odd centimes after conversion.","category":"Ride-hailing fare and surge pricing","checks":7,"contract":"Convert a fare to the payment currency with the directed rate fx[FROM+TO] = [num, den] (half up), then, for cash payments only, round half up to the payment currency cash step (CHF 5 centimes, SEK 100 ore, others 1). Card and wallet payments are not cash-rounded. Return the amount in minor units of the payment currency.","contract_signature":"fare_cents, fare_ccy, pay_ccy, method, fx, cash_step","evaluation_group":"w2-ride-hailing-fare-surge-cash-rounding-fx","failed_approach":"Hard-coding a 5-unit step after conversion ignores the payment currency step and double-rounds.","family":"w2-ride-hailing-fare-surge-cash-rounding-fx-convert-before-rounding","id":"FA-85716","implementations":{"attempt":{"sha256":"aab906411fa43c6801ff433910fe60559cc08009ac118edc9e69dcffe4351b76","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(fare_cents, fare_ccy, pay_ccy, method, fx, cash_step):\n    amt = fare_cents\n    if pay_ccy != fare_ccy:\n        num, den = fx[fare_ccy + pay_ccy]\n        amt = (amt * num * 2 + den) // (2 * den)\n        amt = (amt * 2 + 5) // 10 * 5 if method == 'cash' else amt\n    if method == 'cash':\n        step = cash_step.get(pay_ccy, 1)\n        amt = (amt * 2 + step) // (2 * step) * step\n    return amt\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression: convert before rounding',\n   [1999, 'EUR', 'SEK', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   22900),\n  ('partial repair probe: convert before rounding',\n   [3492, 'CHF', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   3632),\n  ('second regression',\n   [1003, 'EUR', 'SEK', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   11500),\n  ('normal control 1',\n   [1600, 'SEK', 'EUR', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   144),\n  ('normal control 2',\n   [885, 'CHF', 'EUR', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   920),\n  ('normal control 3',\n   [2502, 'EUR', 'CHF', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   2352),\n  ('normal control 4',\n   [1999, 'CHF', 'EUR', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   2079)],\n [('regression: convert before rounding',\n   [1003, 'EUR', 'SEK', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   11500),\n  ('partial repair probe: convert before rounding',\n   [3472, 'SEK', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   312),\n  ('second regression',\n   [2573, 'EUR', 'CHF', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   2420),\n  ('normal control 1',\n   [788, 'EUR', 'CHF', 'card',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   741),\n  ('normal control 2',\n   [2502, 'CHF', 'EUR', 'card',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   2602),\n  ('normal control 3',\n   [1999, 'EUR', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1999),\n  ('normal control 4',\n   [1999, 'SEK', 'EUR', 'card',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   180)],\n [('regression: convert before rounding',\n   [1234, 'EUR', 'CHF', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1160),\n  ('partial repair probe: convert before rounding',\n   [1234, 'SEK', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   111),\n  ('second regression',\n   [1999, 'EUR', 'SEK', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   22900),\n  ('normal control 1',\n   [1566, 'CHF', 'CHF', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1565),\n  ('normal control 2',\n   [1234, 'CHF', 'CHF', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1235),\n  ('normal control 3',\n   [1003, 'SEK', 'EUR', 'card',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   90),\n  ('normal control 4',\n   [1003, 'EUR', 'CHF', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   943)],\n [('regression: convert before rounding',\n   [1234, 'EUR', 'CHF', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1160),\n  ('partial repair probe: convert before rounding',\n   [2502, 'CHF', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   2602),\n  ('second regression',\n   [1451, 'EUR', 'CHF', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1365),\n  ('normal control 1',\n   [1003, 'CHF', 'CHF', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1003),\n  ('normal control 2',\n   [1934, 'EUR', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1934),\n  ('normal control 3',\n   [1999, 'CHF', 'EUR', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   2079),\n  ('normal control 4',\n   [1531, 'EUR', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1531)],\n [('regression: convert before rounding',\n   [1234, 'EUR', 'SEK', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   14200),\n  ('partial repair probe: convert before rounding',\n   [1003, 'CHF', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1043),\n  ('second regression',\n   [1999, 'EUR', 'SEK', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   22900),\n  ('normal control 1',\n   [1999, 'EUR', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1999),\n  ('normal control 2',\n   [1003, 'EUR', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1003),\n  ('normal control 3',\n   [2630, 'SEK', 'EUR', 'card',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   237),\n  ('normal control 4',\n   [2489, 'SEK', 'EUR', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   224)]]\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":"5202bd0a1deb807eb55ced44e42ff5aa0070d4836110f97faeb48c7490a22070","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(fare_cents, fare_ccy, pay_ccy, method, fx, cash_step):\n    amt = fare_cents\n    if method == 'cash':\n        step = cash_step.get(pay_ccy, 1)\n        amt = (amt * 2 + step) // (2 * step) * step\n    if pay_ccy != fare_ccy:\n        num, den = fx[fare_ccy + pay_ccy]\n        amt = (amt * num * 2 + den) // (2 * den)\n    return amt\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression: convert before rounding',\n   [1999, 'EUR', 'SEK', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   22900),\n  ('partial repair probe: convert before rounding',\n   [3492, 'CHF', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   3632),\n  ('second regression',\n   [1003, 'EUR', 'SEK', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   11500),\n  ('normal control 1',\n   [1600, 'SEK', 'EUR', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   144),\n  ('normal control 2',\n   [885, 'CHF', 'EUR', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   920),\n  ('normal control 3',\n   [2502, 'EUR', 'CHF', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   2352),\n  ('normal control 4',\n   [1999, 'CHF', 'EUR', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   2079)],\n [('regression: convert before rounding',\n   [1003, 'EUR', 'SEK', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   11500),\n  ('partial repair probe: convert before rounding',\n   [3472, 'SEK', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   312),\n  ('second regression',\n   [2573, 'EUR', 'CHF', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   2420),\n  ('normal control 1',\n   [788, 'EUR', 'CHF', 'card',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   741),\n  ('normal control 2',\n   [2502, 'CHF', 'EUR', 'card',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   2602),\n  ('normal control 3',\n   [1999, 'EUR', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1999),\n  ('normal control 4',\n   [1999, 'SEK', 'EUR', 'card',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   180)],\n [('regression: convert before rounding',\n   [1234, 'EUR', 'CHF', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1160),\n  ('partial repair probe: convert before rounding',\n   [1234, 'SEK', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   111),\n  ('second regression',\n   [1999, 'EUR', 'SEK', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   22900),\n  ('normal control 1',\n   [1566, 'CHF', 'CHF', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1565),\n  ('normal control 2',\n   [1234, 'CHF', 'CHF', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1235),\n  ('normal control 3',\n   [1003, 'SEK', 'EUR', 'card',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   90),\n  ('normal control 4',\n   [1003, 'EUR', 'CHF', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   943)],\n [('regression: convert before rounding',\n   [1234, 'EUR', 'CHF', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1160),\n  ('partial repair probe: convert before rounding',\n   [2502, 'CHF', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   2602),\n  ('second regression',\n   [1451, 'EUR', 'CHF', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1365),\n  ('normal control 1',\n   [1003, 'CHF', 'CHF', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1003),\n  ('normal control 2',\n   [1934, 'EUR', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1934),\n  ('normal control 3',\n   [1999, 'CHF', 'EUR', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   2079),\n  ('normal control 4',\n   [1531, 'EUR', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1531)],\n [('regression: convert before rounding',\n   [1234, 'EUR', 'SEK', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   14200),\n  ('partial repair probe: convert before rounding',\n   [1003, 'CHF', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1043),\n  ('second regression',\n   [1999, 'EUR', 'SEK', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   22900),\n  ('normal control 1',\n   [1999, 'EUR', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1999),\n  ('normal control 2',\n   [1003, 'EUR', 'EUR', 'cash',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   1003),\n  ('normal control 3',\n   [2630, 'SEK', 'EUR', 'card',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   237),\n  ('normal control 4',\n   [2489, 'SEK', 'EUR', 'wallet',\n    {'CHFEUR': [104, 100], 'EURCHF': [94, 100], 'EURSEK': [1147, 100], 'SEKEUR': [9, 100]},\n    {'CHF': 5, 'SEK': 100}],\n   224)]]\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":"A deterministic toy pricing contract stipulated for this example; it does not reproduce the pricing of any real ride-hailing operator or regulator. 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-ride-hailing-fare-surge-cash-rounding-fx-convert-before-rounding","generated_at":"2026-09-29T14:50:42.919476+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Ride-hailing prices are computed per trip at scale; ordering, unit and boundary slips become systematic over- or under-charging.","root_cause":"Rounding happens in the fare currency before converting.","sha256":"4e03aded35726a539a97a7649473e7afb5e199ba23840e09289dfb07ca9e6626","title":"Cash step applied before currency conversion · 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":41.3,"exit_code":1,"observations":[{"actual":22900,"check":"regression: convert before rounding","expected":22900,"passed":true},{"actual":3630,"check":"partial repair probe: convert before rounding","expected":3632,"passed":false},{"actual":11500,"check":"second regression","expected":11500,"passed":true},{"actual":144,"check":"normal control 1","expected":144,"passed":true},{"actual":920,"check":"normal control 2","expected":920,"passed":true},{"actual":2352,"check":"normal control 3","expected":2352,"passed":true},{"actual":2079,"check":"normal control 4","expected":2079,"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: convert before rounding\", \"actual\": 22900, \"expected\": 22900, \"passed\": true}, {\"check\": \"partial repair probe: convert before rounding\", \"actual\": 3630, \"expected\": 3632, \"passed\": false}, {\"check\": \"second regression\", \"actual\": 11500, \"expected\": 11500, \"passed\": true}, {\"check\": \"normal control 1\", \"actual\": 144, \"expected\": 144, \"passed\": true}, {\"check\": \"normal control 2\", \"actual\": 920, \"expected\": 920, \"passed\": true}, {\"check\": \"normal control 3\", \"actual\": 2352, \"expected\": 2352, \"passed\": true}, {\"check\": \"normal control 4\", \"actual\": 2079, \"expected\": 2079, \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":41.488,"exit_code":1,"observations":[{"actual":22940,"check":"regression: convert before rounding","expected":22900,"passed":false},{"actual":3632,"check":"partial repair probe: convert before rounding","expected":3632,"passed":true},{"actual":11470,"check":"second regression","expected":11500,"passed":false},{"actual":144,"check":"normal control 1","expected":144,"passed":true},{"actual":920,"check":"normal control 2","expected":920,"passed":true},{"actual":2352,"check":"normal control 3","expected":2352,"passed":true},{"actual":2079,"check":"normal control 4","expected":2079,"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: convert before rounding\", \"actual\": 22940, \"expected\": 22900, \"passed\": false}, {\"check\": \"partial repair probe: convert before rounding\", \"actual\": 3632, \"expected\": 3632, \"passed\": true}, {\"check\": \"second regression\", \"actual\": 11470, \"expected\": 11500, \"passed\": false}, {\"check\": \"normal control 1\", \"actual\": 144, \"expected\": 144, \"passed\": true}, {\"check\": \"normal control 2\", \"actual\": 920, \"expected\": 920, \"passed\": true}, {\"check\": \"normal control 3\", \"actual\": 2352, \"expected\": 2352, \"passed\": true}, {\"check\": \"normal control 4\", \"actual\": 2079, \"expected\": 2079, \"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."}}