{"abstract":"W+0.5 is stored as a zero margin win.","category":"Go territory scoring","checks":8,"contract":"Input an SGF RE string. \"0\", \"Draw\", \"Jigo\" -> [\"draw\", 0, \"score\"]; \"Void\" -> [\"void\", None, \"none\"]; C+R/Resign, C+T/Time, C+F/Forfeit (case-insensitive) -> [C, None, reason]; \"C+\" -> [C, None, \"unknown\"]; C+digits with optional one-digit fraction -> [C, tenths, \"score\"]; else unknown.","evaluation_group":"w2-go-territory-scoring-sgf-result","failed_approach":"Assuming every fractional margin is a half point turns W+3.0 into 3.5 and B+2.3 into 2.5.","family":"w2-go-territory-scoring-sgf-result-fractional-margin","id":"FA-83011","implementations":{"attempt":{"sha256":"b9470b57c6e0fff1a835b1294207539814d1769d8ea369ddf65f2d944408aeb8","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    s = x.strip()\n    if s in ('0', 'Draw', 'Jigo'):\n        return ['draw', 0, 'score']\n    if s == 'Void':\n        return ['void', None, 'none']\n    if len(s) < 2 or s[0] not in 'BW' or s[1] != '+':\n        return ['unknown', None, 'none']\n    who = s[0]\n    rest = s[2:]\n    if rest == '':\n        return [who, None, 'unknown']\n    word = rest.lower()\n    for key, reason in (('r', 'resign'), ('t', 'time'), ('f', 'forfeit')):\n        if word in (key, reason):\n            return [who, None, reason]\n    if '.' in rest:\n        whole, _, frac = rest.partition('.')\n    else:\n        whole, frac = rest, '0'\n    if not whole.isdigit() or not frac.isdigit() or len(frac) != 1:\n        return ['unknown', None, 'none']\n    return [who, int(whole) * 10 + 5 * ('.' in rest), 'score']\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['B+3.5', ['B', 35, 'score']], ['W+0.5', ['W', 5, 'score']], ['W+12', ['W', 120, 'score']], ['B+2.3', ['B', 23, 'score']], ['W+8.2', ['W', 82, 'score']], ['B+1.1', ['B', 11, 'score']], ['B+', ['B', None, 'unknown']], ['W+', ['W', None, 'unknown']]], [['W+8.2', ['W', 82, 'score']], ['0', ['draw', 0, 'score']], ['Draw', ['draw', 0, 'score']], ['Jigo', ['draw', 0, 'score']], ['Void', ['void', None, 'none']], ['?', ['unknown', None, 'none']], [' B+R ', ['B', None, 'resign']], ['W+4.1', ['W', 41, 'score']]], [['B+3.5 ', ['B', 35, 'score']], [' W+7', ['W', 70, 'score']], ['X+3', ['unknown', None, 'none']], ['B-3', ['unknown', None, 'none']], ['B+3.25', ['unknown', None, 'none']], ['W+3.0', ['W', 30, 'score']], ['B+6.0', ['B', 60, 'score']], ['B+100.5', ['B', 1005, 'score']]], [['W+0.5', ['W', 5, 'score']], ['W+3.0', ['W', 30, 'score']], ['W+Timeout', ['unknown', None, 'none']], ['B+r', ['B', None, 'resign']], ['W+t', ['W', None, 'time']], ['B+100.5', ['B', 1005, 'score']], ['W+4.1', ['W', 41, 'score']], ['W+.5', ['unknown', None, 'none']]], [['B+R', ['B', None, 'resign']], ['W+Resign', ['W', None, 'resign']], ['B+resign', ['B', None, 'resign']], ['W+T', ['W', None, 'time']], ['B+Time', ['B', None, 'time']], ['B+1.1', ['B', 11, 'score']], ['B+1.1', ['B', 11, 'score']], ['B+7.', ['unknown', None, 'none']]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"result case %d\" % i, 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":"16f985645af57ddf4365a5d2eb1bde6d1eb0fb5aec666d6e82a0dfb104ea1fc6","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    s = x.strip()\n    if s in ('0', 'Draw', 'Jigo'):\n        return ['draw', 0, 'score']\n    if s == 'Void':\n        return ['void', None, 'none']\n    if len(s) < 2 or s[0] not in 'BW' or s[1] != '+':\n        return ['unknown', None, 'none']\n    who = s[0]\n    rest = s[2:]\n    if rest == '':\n        return [who, None, 'unknown']\n    word = rest.lower()\n    for key, reason in (('r', 'resign'), ('t', 'time'), ('f', 'forfeit')):\n        if word in (key, reason):\n            return [who, None, reason]\n    if '.' in rest:\n        whole, _, frac = rest.partition('.')\n    else:\n        whole, frac = rest, '0'\n    if not whole.isdigit() or not frac.isdigit() or len(frac) != 1:\n        return ['unknown', None, 'none']\n    return [who, int(whole) * 10, 'score']\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['B+3.5', ['B', 35, 'score']], ['W+0.5', ['W', 5, 'score']], ['W+12', ['W', 120, 'score']], ['B+2.3', ['B', 23, 'score']], ['W+8.2', ['W', 82, 'score']], ['B+1.1', ['B', 11, 'score']], ['B+', ['B', None, 'unknown']], ['W+', ['W', None, 'unknown']]], [['W+8.2', ['W', 82, 'score']], ['0', ['draw', 0, 'score']], ['Draw', ['draw', 0, 'score']], ['Jigo', ['draw', 0, 'score']], ['Void', ['void', None, 'none']], ['?', ['unknown', None, 'none']], [' B+R ', ['B', None, 'resign']], ['W+4.1', ['W', 41, 'score']]], [['B+3.5 ', ['B', 35, 'score']], [' W+7', ['W', 70, 'score']], ['X+3', ['unknown', None, 'none']], ['B-3', ['unknown', None, 'none']], ['B+3.25', ['unknown', None, 'none']], ['W+3.0', ['W', 30, 'score']], ['B+6.0', ['B', 60, 'score']], ['B+100.5', ['B', 1005, 'score']]], [['W+0.5', ['W', 5, 'score']], ['W+3.0', ['W', 30, 'score']], ['W+Timeout', ['unknown', None, 'none']], ['B+r', ['B', None, 'resign']], ['W+t', ['W', None, 'time']], ['B+100.5', ['B', 1005, 'score']], ['W+4.1', ['W', 41, 'score']], ['W+.5', ['unknown', None, 'none']]], [['B+R', ['B', None, 'resign']], ['W+Resign', ['W', None, 'resign']], ['B+resign', ['B', None, 'resign']], ['W+T', ['W', None, 'time']], ['B+Time', ['B', None, 'time']], ['B+1.1', ['B', 11, 'score']], ['B+1.1', ['B', 11, 'score']], ['B+7.', ['unknown', None, 'none']]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"result case %d\" % i, 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":"c65b3546386e08f9b349c652e3612b8be0efccf96897a77966be5a43d1042443","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    s = x.strip()\n    if s in ('0', 'Draw', 'Jigo'):\n        return ['draw', 0, 'score']\n    if s == 'Void':\n        return ['void', None, 'none']\n    if len(s) < 2 or s[0] not in 'BW' or s[1] != '+':\n        return ['unknown', None, 'none']\n    who = s[0]\n    rest = s[2:]\n    if rest == '':\n        return [who, None, 'unknown']\n    word = rest.lower()\n    for key, reason in (('r', 'resign'), ('t', 'time'), ('f', 'forfeit')):\n        if word in (key, reason):\n            return [who, None, reason]\n    if '.' in rest:\n        whole, _, frac = rest.partition('.')\n    else:\n        whole, frac = rest, '0'\n    if not whole.isdigit() or not frac.isdigit() or len(frac) != 1:\n        return ['unknown', None, 'none']\n    return [who, int(whole) * 10 + int(frac), 'score']\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['B+3.5', ['B', 35, 'score']], ['W+0.5', ['W', 5, 'score']], ['W+12', ['W', 120, 'score']], ['B+2.3', ['B', 23, 'score']], ['W+8.2', ['W', 82, 'score']], ['B+1.1', ['B', 11, 'score']], ['B+', ['B', None, 'unknown']], ['W+', ['W', None, 'unknown']]], [['W+8.2', ['W', 82, 'score']], ['0', ['draw', 0, 'score']], ['Draw', ['draw', 0, 'score']], ['Jigo', ['draw', 0, 'score']], ['Void', ['void', None, 'none']], ['?', ['unknown', None, 'none']], [' B+R ', ['B', None, 'resign']], ['W+4.1', ['W', 41, 'score']]], [['B+3.5 ', ['B', 35, 'score']], [' W+7', ['W', 70, 'score']], ['X+3', ['unknown', None, 'none']], ['B-3', ['unknown', None, 'none']], ['B+3.25', ['unknown', None, 'none']], ['W+3.0', ['W', 30, 'score']], ['B+6.0', ['B', 60, 'score']], ['B+100.5', ['B', 1005, 'score']]], [['W+0.5', ['W', 5, 'score']], ['W+3.0', ['W', 30, 'score']], ['W+Timeout', ['unknown', None, 'none']], ['B+r', ['B', None, 'resign']], ['W+t', ['W', None, 'time']], ['B+100.5', ['B', 1005, 'score']], ['W+4.1', ['W', 41, 'score']], ['W+.5', ['unknown', None, 'none']]], [['B+R', ['B', None, 'resign']], ['W+Resign', ['W', None, 'resign']], ['B+resign', ['B', None, 'resign']], ['W+T', ['W', None, 'time']], ['B+Time', ['B', None, 'time']], ['B+1.1', ['B', 11, 'score']], ['B+1.1', ['B', 11, 'score']], ['B+7.', ['unknown', None, 'none']]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"result case %d\" % i, 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":"Small rectangular toy boards given as strings of B, W and dot; a bounded teaching model of one scoring or bookkeeping rule, not a complete rules engine or server implementation. 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-go-territory-scoring-sgf-result-fractional-margin","generated_at":"2026-09-29T14:50:17.366920+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Go servers and scoring tools compute this value automatically; a wrong answer changes a game result.","repair":"Return whole*10 + fraction digit.","root_cause":"The fractional digit is parsed but not added to the tenths value.","sha256":"da9862c456d9dc0442dad3631b0125ca7b1170ac71066545bfc48bb354a5c429","title":"Half-point margins are truncated to whole points · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":42.645,"exit_code":1,"observations":[{"actual":["B",35,"score"],"check":"result case 0","expected":["B",35,"score"],"passed":true},{"actual":["W",5,"score"],"check":"result case 1","expected":["W",5,"score"],"passed":true},{"actual":["W",120,"score"],"check":"result case 2","expected":["W",120,"score"],"passed":true},{"actual":["B",25,"score"],"check":"result case 3","expected":["B",23,"score"],"passed":false},{"actual":["W",85,"score"],"check":"result case 4","expected":["W",82,"score"],"passed":false},{"actual":["B",15,"score"],"check":"result case 5","expected":["B",11,"score"],"passed":false},{"actual":["B",null,"unknown"],"check":"result case 6","expected":["B",null,"unknown"],"passed":true},{"actual":["W",null,"unknown"],"check":"result case 7","expected":["W",null,"unknown"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"result case 0\", \"actual\": [\"B\", 35, \"score\"], \"expected\": [\"B\", 35, \"score\"], \"passed\": true}, {\"check\": \"result case 1\", \"actual\": [\"W\", 5, \"score\"], \"expected\": [\"W\", 5, \"score\"], \"passed\": true}, {\"check\": \"result case 2\", \"actual\": [\"W\", 120, \"score\"], \"expected\": [\"W\", 120, \"score\"], \"passed\": true}, {\"check\": \"result case 3\", \"actual\": [\"B\", 25, \"score\"], \"expected\": [\"B\", 23, \"score\"], \"passed\": false}, {\"check\": \"result case 4\", \"actual\": [\"W\", 85, \"score\"], \"expected\": [\"W\", 82, \"score\"], \"passed\": false}, {\"check\": \"result case 5\", \"actual\": [\"B\", 15, \"score\"], \"expected\": [\"B\", 11, \"score\"], \"passed\": false}, {\"check\": \"result case 6\", \"actual\": [\"B\", null, \"unknown\"], \"expected\": [\"B\", null, \"unknown\"], \"passed\": true}, {\"check\": \"result case 7\", \"actual\": [\"W\", null, \"unknown\"], \"expected\": [\"W\", null, \"unknown\"], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":44.684,"exit_code":1,"observations":[{"actual":["B",30,"score"],"check":"result case 0","expected":["B",35,"score"],"passed":false},{"actual":["W",0,"score"],"check":"result case 1","expected":["W",5,"score"],"passed":false},{"actual":["W",120,"score"],"check":"result case 2","expected":["W",120,"score"],"passed":true},{"actual":["B",20,"score"],"check":"result case 3","expected":["B",23,"score"],"passed":false},{"actual":["W",80,"score"],"check":"result case 4","expected":["W",82,"score"],"passed":false},{"actual":["B",10,"score"],"check":"result case 5","expected":["B",11,"score"],"passed":false},{"actual":["B",null,"unknown"],"check":"result case 6","expected":["B",null,"unknown"],"passed":true},{"actual":["W",null,"unknown"],"check":"result case 7","expected":["W",null,"unknown"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"result case 0\", \"actual\": [\"B\", 30, \"score\"], \"expected\": [\"B\", 35, \"score\"], \"passed\": false}, {\"check\": \"result case 1\", \"actual\": [\"W\", 0, \"score\"], \"expected\": [\"W\", 5, \"score\"], \"passed\": false}, {\"check\": \"result case 2\", \"actual\": [\"W\", 120, \"score\"], \"expected\": [\"W\", 120, \"score\"], \"passed\": true}, {\"check\": \"result case 3\", \"actual\": [\"B\", 20, \"score\"], \"expected\": [\"B\", 23, \"score\"], \"passed\": false}, {\"check\": \"result case 4\", \"actual\": [\"W\", 80, \"score\"], \"expected\": [\"W\", 82, \"score\"], \"passed\": false}, {\"check\": \"result case 5\", \"actual\": [\"B\", 10, \"score\"], \"expected\": [\"B\", 11, \"score\"], \"passed\": false}, {\"check\": \"result case 6\", \"actual\": [\"B\", null, \"unknown\"], \"expected\": [\"B\", null, \"unknown\"], \"passed\": true}, {\"check\": \"result case 7\", \"actual\": [\"W\", null, \"unknown\"], \"expected\": [\"W\", null, \"unknown\"], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":44.013,"exit_code":0,"observations":[{"actual":["B",35,"score"],"check":"result case 0","expected":["B",35,"score"],"passed":true},{"actual":["W",5,"score"],"check":"result case 1","expected":["W",5,"score"],"passed":true},{"actual":["W",120,"score"],"check":"result case 2","expected":["W",120,"score"],"passed":true},{"actual":["B",23,"score"],"check":"result case 3","expected":["B",23,"score"],"passed":true},{"actual":["W",82,"score"],"check":"result case 4","expected":["W",82,"score"],"passed":true},{"actual":["B",11,"score"],"check":"result case 5","expected":["B",11,"score"],"passed":true},{"actual":["B",null,"unknown"],"check":"result case 6","expected":["B",null,"unknown"],"passed":true},{"actual":["W",null,"unknown"],"check":"result case 7","expected":["W",null,"unknown"],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"result case 0\", \"actual\": [\"B\", 35, \"score\"], \"expected\": [\"B\", 35, \"score\"], \"passed\": true}, {\"check\": \"result case 1\", \"actual\": [\"W\", 5, \"score\"], \"expected\": [\"W\", 5, \"score\"], \"passed\": true}, {\"check\": \"result case 2\", \"actual\": [\"W\", 120, \"score\"], \"expected\": [\"W\", 120, \"score\"], \"passed\": true}, {\"check\": \"result case 3\", \"actual\": [\"B\", 23, \"score\"], \"expected\": [\"B\", 23, \"score\"], \"passed\": true}, {\"check\": \"result case 4\", \"actual\": [\"W\", 82, \"score\"], \"expected\": [\"W\", 82, \"score\"], \"passed\": true}, {\"check\": \"result case 5\", \"actual\": [\"B\", 11, \"score\"], \"expected\": [\"B\", 11, \"score\"], \"passed\": true}, {\"check\": \"result case 6\", \"actual\": [\"B\", null, \"unknown\"], \"expected\": [\"B\", null, \"unknown\"], \"passed\": true}, {\"check\": \"result case 7\", \"actual\": [\"W\", null, \"unknown\"], \"expected\": [\"W\", null, \"unknown\"], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}