{"abstract":"11.99 converts to 12.99 even though 11.99 is already a valid charm price.","category":"Currency rounding and FX conversion","checks":8,"contract":"solve(price, rate, ccy): a price list converted at rate is re-priced to the smallest charm price not below the exact converted value raw = price*rate. For JPY, charm prices end in 8 (…8 yen, i.e. 10k-2). For other currencies, charm prices end in .99. Return the charm price as a plain string.","evaluation_group":"w2-currency_rounding_and_fx_conversion-charm-price-conversion","failed_approach":"Comparing against raw rounded to cents lets sub-cent excess over a charm price through.","family":"w2-currency_rounding_and_fx_conversion-charm-price-conversion-exact-charm-kept","id":"FA-62306","implementations":{"attempt":{"sha256":"13bf911d30ab65725e3e64c904888f7dd46a802f3ae6442489c9f9d00e488c3f","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nfrom decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN\nN = 1\nobservations = []\ndef solve(price, rate, ccy):\n    raw = Decimal(price) * Decimal(rate)\n    if ccy == 'JPY':\n        c = (raw / 10).to_integral_value(rounding=ROUND_CEILING) * 10 - 2\n        if c < raw: c += 10\n        return format(c, 'f')\n    c = raw.to_integral_value(rounding=ROUND_FLOOR) + Decimal('0.99')\n    if c < raw.quantize(Decimal('0.01'), rounding=ROUND_HALF_EVEN): c += 1\n    return format(c, 'f')\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('regression exact-charm-kept 1', ('11.99', '1', 'EUR'), '11.99'),\n  ('regression exact-charm-kept 2', ('132.99', '1', 'GBP'), '132.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: whole number', ('12.00', '1', 'EUR'), '12.99'), ('control: above charm', ('12.995', '1', 'EUR'), '13.99'),\n  ('control: yen round up', ('1234.5', '1', 'JPY'), '1238'),\n  ('control: yen above ending', ('1239', '1', 'JPY'), '1248')],\n [('regression exact-charm-kept 1', ('2759.99', '1', 'USD'), '2759.99'),\n  ('regression exact-charm-kept 2', ('2699.99', '1', 'GBP'), '2699.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: yen round up', ('1234.5', '1', 'JPY'), '1238'),\n  ('control: yen above ending', ('1239', '1', 'JPY'), '1248'),\n  ('control: yen exact ending', ('1238', '1', 'JPY'), '1238'),\n  ('control: converted euro', ('10.00', '0.92', 'EUR'), '9.99')],\n [('regression exact-charm-kept 1', ('2772.99', '1', 'EUR'), '2772.99'),\n  ('regression exact-charm-kept 2', ('632.99', '1', 'USD'), '632.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: converted euro', ('10.00', '0.92', 'EUR'), '9.99'),\n  ('control: yen converted', ('9.99', '151.37', 'JPY'), '1518'),\n  ('control: whole number', ('12.00', '1', 'EUR'), '12.99'),\n  ('control: already charm', ('11.99', '1', 'EUR'), '11.99')],\n [('regression exact-charm-kept 1', ('1442.99', '1', 'USD'), '1442.99'),\n  ('regression exact-charm-kept 2', ('1492.99', '1', 'EUR'), '1492.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: yen converted', ('9.99', '151.37', 'JPY'), '1518'),\n  ('control: whole number', ('12.00', '1', 'EUR'), '12.99'), ('control: already charm', ('11.99', '1', 'EUR'), '11.99'),\n  ('control: above charm', ('12.995', '1', 'EUR'), '13.99')],\n [('regression exact-charm-kept 1', ('1302.99', '1', 'USD'), '1302.99'),\n  ('regression exact-charm-kept 2', ('788.99', '1', 'GBP'), '788.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: above charm', ('12.995', '1', 'EUR'), '13.99'), ('control: yen round up', ('1234.5', '1', 'JPY'), '1238'),\n  ('control: yen above ending', ('1239', '1', 'JPY'), '1248'),\n  ('control: yen exact ending', ('1238', '1', 'JPY'), '1238')]]\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":"951b3ce6db4e8caea4343c1b4042c95eea6acc5daf7306ed13ad9424d004859b","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nfrom decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN\nN = 1\nobservations = []\ndef solve(price, rate, ccy):\n    raw = Decimal(price) * Decimal(rate)\n    if ccy == 'JPY':\n        c = (raw / 10).to_integral_value(rounding=ROUND_CEILING) * 10 - 2\n        if c < raw: c += 10\n        return format(c, 'f')\n    c = raw.to_integral_value(rounding=ROUND_FLOOR) + Decimal('0.99')\n    if c <= raw: c += 1\n    return format(c, 'f')\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('regression exact-charm-kept 1', ('11.99', '1', 'EUR'), '11.99'),\n  ('regression exact-charm-kept 2', ('132.99', '1', 'GBP'), '132.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: whole number', ('12.00', '1', 'EUR'), '12.99'), ('control: above charm', ('12.995', '1', 'EUR'), '13.99'),\n  ('control: yen round up', ('1234.5', '1', 'JPY'), '1238'),\n  ('control: yen above ending', ('1239', '1', 'JPY'), '1248')],\n [('regression exact-charm-kept 1', ('2759.99', '1', 'USD'), '2759.99'),\n  ('regression exact-charm-kept 2', ('2699.99', '1', 'GBP'), '2699.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: yen round up', ('1234.5', '1', 'JPY'), '1238'),\n  ('control: yen above ending', ('1239', '1', 'JPY'), '1248'),\n  ('control: yen exact ending', ('1238', '1', 'JPY'), '1238'),\n  ('control: converted euro', ('10.00', '0.92', 'EUR'), '9.99')],\n [('regression exact-charm-kept 1', ('2772.99', '1', 'EUR'), '2772.99'),\n  ('regression exact-charm-kept 2', ('632.99', '1', 'USD'), '632.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: converted euro', ('10.00', '0.92', 'EUR'), '9.99'),\n  ('control: yen converted', ('9.99', '151.37', 'JPY'), '1518'),\n  ('control: whole number', ('12.00', '1', 'EUR'), '12.99'),\n  ('control: already charm', ('11.99', '1', 'EUR'), '11.99')],\n [('regression exact-charm-kept 1', ('1442.99', '1', 'USD'), '1442.99'),\n  ('regression exact-charm-kept 2', ('1492.99', '1', 'EUR'), '1492.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: yen converted', ('9.99', '151.37', 'JPY'), '1518'),\n  ('control: whole number', ('12.00', '1', 'EUR'), '12.99'), ('control: already charm', ('11.99', '1', 'EUR'), '11.99'),\n  ('control: above charm', ('12.995', '1', 'EUR'), '13.99')],\n [('regression exact-charm-kept 1', ('1302.99', '1', 'USD'), '1302.99'),\n  ('regression exact-charm-kept 2', ('788.99', '1', 'GBP'), '788.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: above charm', ('12.995', '1', 'EUR'), '13.99'), ('control: yen round up', ('1234.5', '1', 'JPY'), '1238'),\n  ('control: yen above ending', ('1239', '1', 'JPY'), '1248'),\n  ('control: yen exact ending', ('1238', '1', 'JPY'), '1238')]]\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":"66c05e85718be18a52a16cc2fa1b19171958df4b519568c638c749d0ae0045c0","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nfrom decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN\nN = 1\nobservations = []\ndef solve(price, rate, ccy):\n    raw = Decimal(price) * Decimal(rate)\n    if ccy == 'JPY':\n        c = (raw / 10).to_integral_value(rounding=ROUND_CEILING) * 10 - 2\n        if c < raw: c += 10\n        return format(c, 'f')\n    c = raw.to_integral_value(rounding=ROUND_FLOOR) + Decimal('0.99')\n    if c < raw: c += 1\n    return format(c, 'f')\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('regression exact-charm-kept 1', ('11.99', '1', 'EUR'), '11.99'),\n  ('regression exact-charm-kept 2', ('132.99', '1', 'GBP'), '132.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: whole number', ('12.00', '1', 'EUR'), '12.99'), ('control: above charm', ('12.995', '1', 'EUR'), '13.99'),\n  ('control: yen round up', ('1234.5', '1', 'JPY'), '1238'),\n  ('control: yen above ending', ('1239', '1', 'JPY'), '1248')],\n [('regression exact-charm-kept 1', ('2759.99', '1', 'USD'), '2759.99'),\n  ('regression exact-charm-kept 2', ('2699.99', '1', 'GBP'), '2699.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: yen round up', ('1234.5', '1', 'JPY'), '1238'),\n  ('control: yen above ending', ('1239', '1', 'JPY'), '1248'),\n  ('control: yen exact ending', ('1238', '1', 'JPY'), '1238'),\n  ('control: converted euro', ('10.00', '0.92', 'EUR'), '9.99')],\n [('regression exact-charm-kept 1', ('2772.99', '1', 'EUR'), '2772.99'),\n  ('regression exact-charm-kept 2', ('632.99', '1', 'USD'), '632.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: converted euro', ('10.00', '0.92', 'EUR'), '9.99'),\n  ('control: yen converted', ('9.99', '151.37', 'JPY'), '1518'),\n  ('control: whole number', ('12.00', '1', 'EUR'), '12.99'),\n  ('control: already charm', ('11.99', '1', 'EUR'), '11.99')],\n [('regression exact-charm-kept 1', ('1442.99', '1', 'USD'), '1442.99'),\n  ('regression exact-charm-kept 2', ('1492.99', '1', 'EUR'), '1492.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: yen converted', ('9.99', '151.37', 'JPY'), '1518'),\n  ('control: whole number', ('12.00', '1', 'EUR'), '12.99'), ('control: already charm', ('11.99', '1', 'EUR'), '11.99'),\n  ('control: above charm', ('12.995', '1', 'EUR'), '13.99')],\n [('regression exact-charm-kept 1', ('1302.99', '1', 'USD'), '1302.99'),\n  ('regression exact-charm-kept 2', ('788.99', '1', 'GBP'), '788.99'),\n  ('partial repair guard 1', ('11.994', '1', 'USD'), '12.99'),\n  ('partial repair guard 2', ('11.99004', '1', 'GBP'), '12.99'),\n  ('control: above charm', ('12.995', '1', 'EUR'), '13.99'), ('control: yen round up', ('1234.5', '1', 'JPY'), '1238'),\n  ('control: yen above ending', ('1239', '1', 'JPY'), '1248'),\n  ('control: yen exact ending', ('1238', '1', 'JPY'), '1238')]]\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":"A deterministic, bounded teaching model with a stipulated toy contract; it makes no claim of conformance to any real regulation, standard, or institution's rules. 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-currency_rounding_and_fx_conversion-charm-price-conversion-exact-charm-kept","generated_at":"2026-09-29T14:47:03.369890+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Currency amounts must be rounded at the right stage and in the right unit, or ledgers, quotes and settlements drift by minor units.","repair":"Only bump when the candidate is strictly below the exact value.","root_cause":"The bump condition uses c <= raw.","sha256":"56b7c31da356f13659cce2998e666c16e1b2976d234394a7682d5258462f94ef","title":"A converted value already on a charm price is bumped to the next one · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":40.733,"exit_code":1,"observations":[{"actual":"11.99","check":"regression exact-charm-kept 1","expected":"11.99","passed":true},{"actual":"132.99","check":"regression exact-charm-kept 2","expected":"132.99","passed":true},{"actual":"11.99","check":"partial repair guard 1","expected":"12.99","passed":false},{"actual":"11.99","check":"partial repair guard 2","expected":"12.99","passed":false},{"actual":"12.99","check":"control: whole number","expected":"12.99","passed":true},{"actual":"13.99","check":"control: above charm","expected":"13.99","passed":true},{"actual":"1238","check":"control: yen round up","expected":"1238","passed":true},{"actual":"1248","check":"control: yen above ending","expected":"1248","passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression exact-charm-kept 1\", \"actual\": \"11.99\", \"expected\": \"11.99\", \"passed\": true}, {\"check\": \"regression exact-charm-kept 2\", \"actual\": \"132.99\", \"expected\": \"132.99\", \"passed\": true}, {\"check\": \"partial repair guard 1\", \"actual\": \"11.99\", \"expected\": \"12.99\", \"passed\": false}, {\"check\": \"partial repair guard 2\", \"actual\": \"11.99\", \"expected\": \"12.99\", \"passed\": false}, {\"check\": \"control: whole number\", \"actual\": \"12.99\", \"expected\": \"12.99\", \"passed\": true}, {\"check\": \"control: above charm\", \"actual\": \"13.99\", \"expected\": \"13.99\", \"passed\": true}, {\"check\": \"control: yen round up\", \"actual\": \"1238\", \"expected\": \"1238\", \"passed\": true}, {\"check\": \"control: yen above ending\", \"actual\": \"1248\", \"expected\": \"1248\", \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.942,"exit_code":1,"observations":[{"actual":"12.99","check":"regression exact-charm-kept 1","expected":"11.99","passed":false},{"actual":"133.99","check":"regression exact-charm-kept 2","expected":"132.99","passed":false},{"actual":"12.99","check":"partial repair guard 1","expected":"12.99","passed":true},{"actual":"12.99","check":"partial repair guard 2","expected":"12.99","passed":true},{"actual":"12.99","check":"control: whole number","expected":"12.99","passed":true},{"actual":"13.99","check":"control: above charm","expected":"13.99","passed":true},{"actual":"1238","check":"control: yen round up","expected":"1238","passed":true},{"actual":"1248","check":"control: yen above ending","expected":"1248","passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression exact-charm-kept 1\", \"actual\": \"12.99\", \"expected\": \"11.99\", \"passed\": false}, {\"check\": \"regression exact-charm-kept 2\", \"actual\": \"133.99\", \"expected\": \"132.99\", \"passed\": false}, {\"check\": \"partial repair guard 1\", \"actual\": \"12.99\", \"expected\": \"12.99\", \"passed\": true}, {\"check\": \"partial repair guard 2\", \"actual\": \"12.99\", \"expected\": \"12.99\", \"passed\": true}, {\"check\": \"control: whole number\", \"actual\": \"12.99\", \"expected\": \"12.99\", \"passed\": true}, {\"check\": \"control: above charm\", \"actual\": \"13.99\", \"expected\": \"13.99\", \"passed\": true}, {\"check\": \"control: yen round up\", \"actual\": \"1238\", \"expected\": \"1238\", \"passed\": true}, {\"check\": \"control: yen above ending\", \"actual\": \"1248\", \"expected\": \"1248\", \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":38.341,"exit_code":0,"observations":[{"actual":"11.99","check":"regression exact-charm-kept 1","expected":"11.99","passed":true},{"actual":"132.99","check":"regression exact-charm-kept 2","expected":"132.99","passed":true},{"actual":"12.99","check":"partial repair guard 1","expected":"12.99","passed":true},{"actual":"12.99","check":"partial repair guard 2","expected":"12.99","passed":true},{"actual":"12.99","check":"control: whole number","expected":"12.99","passed":true},{"actual":"13.99","check":"control: above charm","expected":"13.99","passed":true},{"actual":"1238","check":"control: yen round up","expected":"1238","passed":true},{"actual":"1248","check":"control: yen above ending","expected":"1248","passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression exact-charm-kept 1\", \"actual\": \"11.99\", \"expected\": \"11.99\", \"passed\": true}, {\"check\": \"regression exact-charm-kept 2\", \"actual\": \"132.99\", \"expected\": \"132.99\", \"passed\": true}, {\"check\": \"partial repair guard 1\", \"actual\": \"12.99\", \"expected\": \"12.99\", \"passed\": true}, {\"check\": \"partial repair guard 2\", \"actual\": \"12.99\", \"expected\": \"12.99\", \"passed\": true}, {\"check\": \"control: whole number\", \"actual\": \"12.99\", \"expected\": \"12.99\", \"passed\": true}, {\"check\": \"control: above charm\", \"actual\": \"13.99\", \"expected\": \"13.99\", \"passed\": true}, {\"check\": \"control: yen round up\", \"actual\": \"1238\", \"expected\": \"1238\", \"passed\": true}, {\"check\": \"control: yen above ending\", \"actual\": \"1248\", \"expected\": \"1248\", \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}