{"abstract":"Reverse komi of -6.5 is applied as +6.5.","category":"Go territory scoring","checks":8,"contract":"Input a komi string: optional sign, whole points, and an optional half written \".5\"/\".0\" or \"½\". A bare half (\"½\", \".5\") is allowed. Return komi in tenths or \"invalid\".","evaluation_group":"w2-go-territory-scoring-komi-parse","failed_approach":"Negating only the whole part turns -0.5 into +0.5 and -6.5 into -5.5.","family":"w2-go-territory-scoring-komi-parse-negative-half-sign","id":"FA-83301","implementations":{"attempt":{"sha256":"9e8a35cfa7f9c8cd5553b030d3b007d2a6328d36387c95acff4f977b9bd49894","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    s = x.strip()\n    neg = s.startswith('-')\n    if s[:1] in '+-' and s:\n        s = s[1:]\n    half = 0\n    if s.endswith('½'):\n        half = 5\n        s = s[:-1]\n    elif '.' in s:\n        s, _, frac = s.partition('.')\n        if frac not in ('0', '5'):\n            return 'invalid'\n        half = int(frac)\n    if not s.isdigit():\n        if s == '' and half:\n            s = '0'\n        else:\n            return 'invalid'\n    v = int(s) * 10 + half\n    return -int(s) * 10 + half if neg else v\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['-0.5', -5], ['-0.5', -5], ['+5.5', 55], ['7.0', 70], ['6.3', 'invalid'], ['.5', 5], ['', 'invalid'], ['-', 'invalid']], [['abc', 'invalid'], ['5.', 'invalid'], [' 6.5 ', 65], ['-3', -30], ['-7.5', -75], ['-7.5', -75], ['0.0', 0], ['1 1/2', 'invalid']], [['6.5', 65], ['7', 70], ['-0.5', -5], ['-6½', -65], ['-3', -30], ['6.50', 'invalid'], ['+', 'invalid'], ['+½', 5]], [['-0.5', -5], ['½', 5], ['-6½', -65], ['0', 0], ['+5.5', 55], ['7.0', 70], ['6.3', 'invalid'], ['.5', 5]], [['-0.5', -5], ['', 'invalid'], ['-', 'invalid'], ['abc', 'invalid'], ['5.', 'invalid'], [' 6.5 ', 65], ['-3', -30], ['-7.5', -75]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"komi 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":"9e3c4eb9587b2afae765bd43dbb84c248eee219d66c72d753fac99142c0d1d52","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    s = x.strip()\n    neg = s.startswith('-')\n    if s[:1] in '+-' and s:\n        s = s[1:]\n    half = 0\n    if s.endswith('½'):\n        half = 5\n        s = s[:-1]\n    elif '.' in s:\n        s, _, frac = s.partition('.')\n        if frac not in ('0', '5'):\n            return 'invalid'\n        half = int(frac)\n    if not s.isdigit():\n        if s == '' and half:\n            s = '0'\n        else:\n            return 'invalid'\n    v = int(s) * 10 + half\n    return v\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['-0.5', -5], ['-0.5', -5], ['+5.5', 55], ['7.0', 70], ['6.3', 'invalid'], ['.5', 5], ['', 'invalid'], ['-', 'invalid']], [['abc', 'invalid'], ['5.', 'invalid'], [' 6.5 ', 65], ['-3', -30], ['-7.5', -75], ['-7.5', -75], ['0.0', 0], ['1 1/2', 'invalid']], [['6.5', 65], ['7', 70], ['-0.5', -5], ['-6½', -65], ['-3', -30], ['6.50', 'invalid'], ['+', 'invalid'], ['+½', 5]], [['-0.5', -5], ['½', 5], ['-6½', -65], ['0', 0], ['+5.5', 55], ['7.0', 70], ['6.3', 'invalid'], ['.5', 5]], [['-0.5', -5], ['', 'invalid'], ['-', 'invalid'], ['abc', 'invalid'], ['5.', 'invalid'], [' 6.5 ', 65], ['-3', -30], ['-7.5', -75]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"komi 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":"893def30b2128476b438b2fa17e8e1c50292c9d79c0d9c5043515061e7dd7865","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    s = x.strip()\n    neg = s.startswith('-')\n    if s[:1] in '+-' and s:\n        s = s[1:]\n    half = 0\n    if s.endswith('½'):\n        half = 5\n        s = s[:-1]\n    elif '.' in s:\n        s, _, frac = s.partition('.')\n        if frac not in ('0', '5'):\n            return 'invalid'\n        half = int(frac)\n    if not s.isdigit():\n        if s == '' and half:\n            s = '0'\n        else:\n            return 'invalid'\n    v = int(s) * 10 + half\n    return -v if neg else v\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['-0.5', -5], ['-0.5', -5], ['+5.5', 55], ['7.0', 70], ['6.3', 'invalid'], ['.5', 5], ['', 'invalid'], ['-', 'invalid']], [['abc', 'invalid'], ['5.', 'invalid'], [' 6.5 ', 65], ['-3', -30], ['-7.5', -75], ['-7.5', -75], ['0.0', 0], ['1 1/2', 'invalid']], [['6.5', 65], ['7', 70], ['-0.5', -5], ['-6½', -65], ['-3', -30], ['6.50', 'invalid'], ['+', 'invalid'], ['+½', 5]], [['-0.5', -5], ['½', 5], ['-6½', -65], ['0', 0], ['+5.5', 55], ['7.0', 70], ['6.3', 'invalid'], ['.5', 5]], [['-0.5', -5], ['', 'invalid'], ['-', 'invalid'], ['abc', 'invalid'], ['5.', 'invalid'], [' 6.5 ', 65], ['-3', -30], ['-7.5', -75]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"komi 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-komi-parse-negative-half-sign","generated_at":"2026-09-29T14:50:20.260972+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":"Negate the complete value when the sign is minus.","root_cause":"The parsed sign flag is never applied.","sha256":"af08b6172a03671f7aa082c8c72fd59d89d43eed325dca4c829e7fe1698615f0","title":"Negative komi loses its sign · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":40.183,"exit_code":1,"observations":[{"actual":5,"check":"komi case 0","expected":-5,"passed":false},{"actual":5,"check":"komi case 1","expected":-5,"passed":false},{"actual":55,"check":"komi case 2","expected":55,"passed":true},{"actual":70,"check":"komi case 3","expected":70,"passed":true},{"actual":"invalid","check":"komi case 4","expected":"invalid","passed":true},{"actual":5,"check":"komi case 5","expected":5,"passed":true},{"actual":"invalid","check":"komi case 6","expected":"invalid","passed":true},{"actual":"invalid","check":"komi case 7","expected":"invalid","passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"komi case 0\", \"actual\": 5, \"expected\": -5, \"passed\": false}, {\"check\": \"komi case 1\", \"actual\": 5, \"expected\": -5, \"passed\": false}, {\"check\": \"komi case 2\", \"actual\": 55, \"expected\": 55, \"passed\": true}, {\"check\": \"komi case 3\", \"actual\": 70, \"expected\": 70, \"passed\": true}, {\"check\": \"komi case 4\", \"actual\": \"invalid\", \"expected\": \"invalid\", \"passed\": true}, {\"check\": \"komi case 5\", \"actual\": 5, \"expected\": 5, \"passed\": true}, {\"check\": \"komi case 6\", \"actual\": \"invalid\", \"expected\": \"invalid\", \"passed\": true}, {\"check\": \"komi case 7\", \"actual\": \"invalid\", \"expected\": \"invalid\", \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":41.754,"exit_code":1,"observations":[{"actual":5,"check":"komi case 0","expected":-5,"passed":false},{"actual":5,"check":"komi case 1","expected":-5,"passed":false},{"actual":55,"check":"komi case 2","expected":55,"passed":true},{"actual":70,"check":"komi case 3","expected":70,"passed":true},{"actual":"invalid","check":"komi case 4","expected":"invalid","passed":true},{"actual":5,"check":"komi case 5","expected":5,"passed":true},{"actual":"invalid","check":"komi case 6","expected":"invalid","passed":true},{"actual":"invalid","check":"komi case 7","expected":"invalid","passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"komi case 0\", \"actual\": 5, \"expected\": -5, \"passed\": false}, {\"check\": \"komi case 1\", \"actual\": 5, \"expected\": -5, \"passed\": false}, {\"check\": \"komi case 2\", \"actual\": 55, \"expected\": 55, \"passed\": true}, {\"check\": \"komi case 3\", \"actual\": 70, \"expected\": 70, \"passed\": true}, {\"check\": \"komi case 4\", \"actual\": \"invalid\", \"expected\": \"invalid\", \"passed\": true}, {\"check\": \"komi case 5\", \"actual\": 5, \"expected\": 5, \"passed\": true}, {\"check\": \"komi case 6\", \"actual\": \"invalid\", \"expected\": \"invalid\", \"passed\": true}, {\"check\": \"komi case 7\", \"actual\": \"invalid\", \"expected\": \"invalid\", \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":39.557,"exit_code":0,"observations":[{"actual":-5,"check":"komi case 0","expected":-5,"passed":true},{"actual":-5,"check":"komi case 1","expected":-5,"passed":true},{"actual":55,"check":"komi case 2","expected":55,"passed":true},{"actual":70,"check":"komi case 3","expected":70,"passed":true},{"actual":"invalid","check":"komi case 4","expected":"invalid","passed":true},{"actual":5,"check":"komi case 5","expected":5,"passed":true},{"actual":"invalid","check":"komi case 6","expected":"invalid","passed":true},{"actual":"invalid","check":"komi case 7","expected":"invalid","passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"komi case 0\", \"actual\": -5, \"expected\": -5, \"passed\": true}, {\"check\": \"komi case 1\", \"actual\": -5, \"expected\": -5, \"passed\": true}, {\"check\": \"komi case 2\", \"actual\": 55, \"expected\": 55, \"passed\": true}, {\"check\": \"komi case 3\", \"actual\": 70, \"expected\": 70, \"passed\": true}, {\"check\": \"komi case 4\", \"actual\": \"invalid\", \"expected\": \"invalid\", \"passed\": true}, {\"check\": \"komi case 5\", \"actual\": 5, \"expected\": 5, \"passed\": true}, {\"check\": \"komi case 6\", \"actual\": \"invalid\", \"expected\": \"invalid\", \"passed\": true}, {\"check\": \"komi case 7\", \"actual\": \"invalid\", \"expected\": \"invalid\", \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}